Skip to content

fix(behavior): stop refusing a cohort over frame-rate jitter - #102

Merged
gbradham merged 1 commit into
mainfrom
fix/fps-jitter-tolerance
Aug 5, 2026
Merged

fix(behavior): stop refusing a cohort over frame-rate jitter#102
gbradham merged 1 commit into
mainfrom
fix/fps-jitter-tolerance

Conversation

@gbradham

@gbradham gbradham commented Aug 5, 2026

Copy link
Copy Markdown
Member

What

resolve_sessions_fps grouped recorded frame rates by rounding to three
decimal places
, then refused to train if more than one group survived.

Container timestamps don't cooperate with that. Thirty sidecars written off one
camera in a single session read:

29.979620  30.000000  30.000727      spread 0.021107 fps  =  0.0704%

Over an 8-frame window that is 0.19 ms. It made a perfectly uniform cohort
untrainable, with an error listing 30 files as though they'd been recorded
differently.

The guard itself is worth keeping — it exists so one rolling window cannot mean
two durations inside a model. But the differences it's for are 25 vs 30 (20%)
and 30 vs 60 (100%). This groups rates within 2%, so encoder wobble and the
29.97/30.0 naming convention collapse into one rate while a genuine mismatch
still fails loudly. The resolved rate is the group mean, within tolerance of
every member by construction.

The advice you couldn't take

The error said to "pass fps= to force one rate" — but _shared_options()
never sent fps and no widget offered it, so from the GUI that was a dead end.
Adds a Frame rate spin box defaulting to auto (from pose CSVs), with 0
shown as the special "auto" value so a literal 0 fps can't reach the pipeline.

Verified against the real cohort

34 sessions whose sidecars carry the spread above:

result
before ValueError: these sessions were recorded at different frame rates (29.98 fps: …; 30.0 fps: …; 30.001 fps: …)
after resolves to 29.999161 fps

Found because the cohort trained fine from a folder with no sidecars — falling
back to DEFAULT_FPS — and broke the moment it moved to a folder that had
them. Recording more metadata made it fail.

Tests

  • Encoder jitter (the three real values) resolves to one rate
  • 29.97 vs 30.0 resolves to one rate
  • 25 vs 30 still refused, and 30 vs 60 still refused — the guard's purpose
    is covered in both directions
  • The refusal still names the offending rates and their session files
  • Train tab: auto sends fps=None, a set value reaches the pipeline, 0 renders
    as "auto", and all three entry points accept fps

2803 passed, 1 skipped; ruff and black clean.

Note: an earlier full-suite run reported one failure that passed on re-run and
did not recur. I was unable to capture its name, so I'm flagging it as a
suspected pre-existing flake rather than claiming a clean first pass.

`resolve_sessions_fps` grouped recorded rates by rounding to three decimal
places and refused to train if more than one group survived. Container
timestamps do not cooperate with that: thirty sidecars written off one
camera in one session read 29.979620, 30.000000 and 30.000727. That is a
0.07% spread -- 0.19 ms across an eight-frame window -- and it made a
perfectly uniform cohort untrainable.

The guard is worth keeping; it exists so one rolling window cannot mean two
durations in the same model. But the differences it is for are 25 vs 30 and
30 vs 60, which are 20% and 100% apart. Group rates within 2% instead, so
encoder wobble and the 29.97/30.0 naming convention collapse to one rate
while a genuine mismatch still fails loudly. The resolved rate is the mean
of the group, within tolerance of every member by construction.

The error also advised passing `fps=` to force a rate, which the Train tab
had no way to do -- `_shared_options` never sent one and no widget offered
it. Add a frame-rate spin box defaulting to "auto (from pose CSVs)", so the
advice names something reachable and a genuinely mixed cohort can still be
trained deliberately.

Found on a 34-session cohort that trained fine from a folder with no
sidecars and failed the moment it moved to one that had them.
@gbradham
gbradham merged commit 0245c86 into main Aug 5, 2026
4 checks passed
@gbradham
gbradham deleted the fix/fps-jitter-tolerance branch August 5, 2026 19:27
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