sleap-nn v0.3.2 Release Notes
Summary
SLEAP-NN v0.3.2 is a small correctness-focused follow-up to v0.3.1, fixing a cluster of predict/track parity bugs (--input_scale overrides, empty-frame retention, tracking-log fidelity), guarding eval against zero-matched-instance crashes/warning-spam, fixing sparse eval metrics in training_log.csv, adding a JSON sibling for evaluation metrics, fixing .pkg.slp inference outputs referencing the wrong video by default, and fixing legacy config conversion silently dropping flip augmentation. 10 PRs since v0.3.1.
Installation
# Install / upgrade the CLI tool (auto-selects the right torch backend)
uv tool install sleap-nn --torch-backend auto --upgrade
# Verify
sleap-nn --version
# Expected output: sleap-nn 0.3.2Breaking Changes
sleap-nn predict now retains empty-detection frames by default (#717)
Previously, non-tracking predict runs silently dropped every zero-detection frame from the output .slp, while track runs kept them. predict now retains one output frame per zero-detection frame by default, matching track and legacy SLEAP behavior. Pass --no_empty_frames to restore the old drop-empty-frames behavior.
predict now backreferences a .pkg.slp input to itself, not its source video (#724)
--restore_source_videos (and the predict()/save_predictions()/run_sam_segmentation() API kwarg of the same name) now defaults to false. Previously, saving predictions from a .pkg.slp input restored a reference to the pre-embedding source video by default — a file that's frequently not available (that's the point of a .pkg.slp), which could leave the output unable to display images at all. The output now backreferences the .pkg.slp itself by default, matching sleap-nn track's existing behavior. Pass --restore_source_videos to restore the old behavior. This also fixes a related bug where, for some inputs, the output could end up self-referentially pointing at itself instead of any video at all.
New Features
Evaluation
- JSON sibling of pickled
.npzmetrics (#721) — training/eval now also writes ametrics.{split}.{idx}.jsonfile next to the existing pickled.npz, so non-Python tooling (e.g. the sleap-app metrics UI) can read evaluation metrics directly without a numpy/pickle dependency..npzoutput is unchanged.
CLI Updates
sleap-nn predict --guimode hardening (#715) — log output is now cleanly routed to stderr so it can no longer interleave with and corrupt the--guimode's JSON progress-line parsing; runtime failures during--guiruns now also emit a structured JSON error line before raising.- Duplicate
--model_pathsof the same model type now raises a clear error (#715) — previously silently discarded one of the paths. --input_scaleoverride fixed for bothpredictandtrack(#716) — see Fixes.predictretains empty-detection frames by default (#717) — see Breaking Changes.--restore_source_videosnow defaults tofalse(#724) — see Breaking Changes.
Fixes
- Fixed
predict --trackingproducing different track-ID assignments thantrack --tracking: empty-detection frames were dropped before tracking, skewing the candidate window's view of elapsed time; empty frames are now retained through tracking so identities flush/persist exactly as legacy does (#714). - Fixed
--input_scaleoverride being broken in both CLIs when set to something other than the training-time value:predictsilently ignored the override entirely, whiletrackapplied it to the forward resize but not the coordinate rescale-back, producing out-of-frame keypoint coordinates. Both pipelines now correctly resolve and apply the override end-to-end (#716). - Fixed a tracking-logging bug that silently swallowed several tracking/model-resolution notices, and restored several legacy log lines (startup banner, per-filter config, save-path confirmation, tracking timing) so
predictoutput parity-matchestrackfor debugging (#717). - A fully collapsed eval split (0 matched instances) no longer spams
RuntimeWarning: Mean of empty slicefrom OKS/PCK/VOC metric calculations in either the training eval loop or the standalonesleap-nn evalCLI — it now logs one clear message and skips cleanly (#720). - Fixed sparse eval metrics in
training_log.csv: whentrainer_config.eval.frequencyruns eval only every N epochs, the CSV previously either omitted eval columns entirely or silently repeated the last-computed value on non-eval epochs. Eval columns are now always included and correctly showNaNon epochs where eval didn't run, so progress plots aren't misled by stale carry-forward values (#722). - Fixed
predict(andrun_sam_segmentation) saving a.pkg.slpinput's output with a broken video reference:VideoProvider/LabelsProviderclose the video's backend to cheaply copy it for the prefetch thread, and the closed backend was never reopened before the final save, so sleap-io's embedded-image detection missed it and the output could end up self-referentially pointing at itself instead of any real video. The backend is now reopened right after the thread-local copy is made (#724). - Fixed legacy SLEAP JSON training-config conversion silently dropping flip augmentation:
data_mapper()never read the legacyoptimization.augmentation_config.random_flip/flip_horizontalfields, so importing an old config with flip enabled produced a sleap-nn config with flip silently disabled.random_flip=True+flip_horizontal=Truenow correctly maps toGeometricConfig.flip_p=0.5; a legacy vertical flip (flip_horizontal=False, unsupported by sleap-nn's horizontal-only flip) now logs a warning instead of silently doing nothing (#723).
Dependencies & Build
- sleap-io pin unchanged at
>=0.9.2,<0.10.0— 0.9.2 remains the latest release on both PyPI and GitHub, so no upper-bound audit was needed this cycle.
Upgrade Notes
- If your workflow depends on
predictsilently dropping zero-detection frames, add--no_empty_frames(#717). - If your workflow depends on
predictrestoring the pre-embedding source video reference for.pkg.slpinputs, add--restore_source_videos(#724). - If you pin
sleap-io, no change needed —>=0.9.2,<0.10.0is still current.
Changelog
- #714: Make predict --tracking see empty-detection frames, matching legacy (@gitttt-1234)
- #715: Predict-pipeline robustness hardening (3 small fixes) (@gitttt-1234)
- #716: Fix --input_scale override in both predict and track (@gitttt-1234)
- #717: Empty-frame retention, tracking-logging bug, and legacy log-line parity (@gitttt-1234)
- #720: Guard zero-matched-instance warnings + retire legacy predict pipeline from post-training eval (@gitttt-1234)
- #721: Emit a JSON sibling of the pickled .npz metrics (@alicup29)
- #722: NaN-fill sparse eval metrics in training_log.csv instead of stale carry-forward (@gitttt-1234)
- #723: Convert legacy random_flip/flip_horizontal to flip_p (@gitttt-1234)
- #724: Bump version to 0.3.2; fix
.pkg.slppredict output referencing the wrong video by default (@gitttt-1234)
Contributors: @gitttt-1234, @alicup29
Full Changelog: v0.3.1...v0.3.2