utils
sleap_nn.config.utils
¶
Utilities for config building and validation.
Functions:
| Name | Description |
|---|---|
check_centroid_methods |
Validate every head config's centroid-method knobs (#586). |
check_num_workers |
Resolve |
check_output_strides |
Check max_stride and output_stride in backbone_config with head_config. |
check_tiling |
Validate + reconcile tiling geometry against the finalized backbone/head. |
check_tiling_parity |
Re-check inference tiling geometry against the trained model config. |
get_backbone_type_from_cfg |
Return the backbone type from the config. One of [unet, swint, convnext]. |
get_model_type_from_cfg |
Return the model type from the config. One of [single_instance, centroid, centered_instance, bottomup]. |
get_output_strides_from_heads |
Get list of output strides from head configs. |
oneof |
Ensure that the decorated attrs class only has a single attribute set. |
resolve_auto_num_workers |
Pick a dataloader worker count for |
resolve_model_dir |
Resolve a user-supplied model path to its model directory. |
suggest_num_workers |
Hint that a cached run is leaving dataloading throughput on the table. |
usable_cpu_count |
Return the number of CPUs actually usable by this process. |
check_centroid_methods(config)
¶
Validate every head config's centroid-method knobs (#586).
A contradictory pair (anchor_part plus a non-anchor centroid_method)
or an unknown method name must fail at setup with a message naming the head,
not deep inside the first __getitem__ of a dataloader worker — where the
traceback is a multiprocessing wrapper and the run has already spent minutes
caching images.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
OmegaConf
|
The full training job config. |
required |
Returns:
| Type | Description |
|---|---|
OmegaConf
|
The config, unchanged (validation only). |
Raises:
| Type | Description |
|---|---|
ValueError
|
For any head whose centroid knobs do not resolve. |
Source code in sleap_nn/config/utils.py
check_num_workers(config, train_labels=None, val_labels=None, memory_buffer=0.2)
¶
Resolve num_workers: "auto" on the train/val dataloader configs.
Resolution happens once, up front, and the resolved integer is written back
into the config so that every downstream consumer (dataloader construction,
cache-memory estimation) sees a plain int, and the saved
training_config.yaml records the worker count the run actually used.
initial_config.yaml keeps the literal "auto", so a config reused on
another machine re-resolves there.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
OmegaConf
|
The full training job config. |
required |
train_labels
|
Optional[list]
|
Training labels. Passing them lets |
None
|
val_labels
|
Optional[list]
|
Validation labels, as above. |
None
|
memory_buffer
|
float
|
Fraction of memory reserved for training overhead. |
0.2
|
Also emits a one-line hint when a caching pipeline is configured with fewer
workers than this machine could actually support — see
:func:suggest_num_workers.
Returns:
| Type | Description |
|---|---|
OmegaConf
|
The config with any |
Source code in sleap_nn/config/utils.py
check_output_strides(config)
¶
Check max_stride and output_stride in backbone_config with head_config.
Source code in sleap_nn/config/utils.py
check_tiling(config)
¶
Validate + reconcile tiling geometry against the finalized backbone/head.
No-op unless data_config.preprocessing.tiling.enabled is True.
Must run after :func:check_output_strides so max_stride /
output_stride are finalized, and after _setup_tiling_config has
auto-sized tile_size / overlap from the labels. Enforces:
- GUARD: pretrained-encoder / non-(unet|convnext|swint) backbone -> ValueError.
- GUARD:
multi_class_topdown/ ClassVectorsHead -> ValueError. tile_sizedivisible bylcm(max_stride, output_stride)(rounds UP + warns).overlapdivisible byoutput_stride,>= min_overlap_fraction * tile_size(raises overlap + warns), and0 <= overlap < tile_size(else ValueError).
Guards are enforced explicitly here (not via attrs validators) because
_setup_tiling_config mutates the config in place on the OmegaConf object,
which does not re-run attrs validators.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
OmegaConf
|
The (finalized) training/inference config. |
required |
Returns:
| Type | Description |
|---|---|
OmegaConf
|
The config, mutated in place with reconciled tiling geometry. |
Source code in sleap_nn/config/utils.py
664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | |
check_tiling_parity(config, tile_size_override=None, overlap_override=None)
¶
Re-check inference tiling geometry against the trained model config.
Tiling requires train-time == infer-time geometry (scale parity); the trained geometry lives in the model config. A user-supplied geometry override that diverges from the trained values requires a retrain, so this raises on a mismatch. No-op unless tiling is enabled.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
OmegaConf
|
The loaded (trained) model config. |
required |
tile_size_override
|
Optional[int]
|
Optional inference-time |
None
|
overlap_override
|
Optional[int]
|
Optional inference-time |
None
|
Returns:
| Type | Description |
|---|---|
OmegaConf
|
The config unchanged (parity check only). |
Source code in sleap_nn/config/utils.py
get_backbone_type_from_cfg(config)
¶
Return the backbone type from the config. One of [unet, swint, convnext].
Source code in sleap_nn/config/utils.py
get_model_type_from_cfg(config)
¶
Return the model type from the config. One of [single_instance, centroid, centered_instance, bottomup].
Source code in sleap_nn/config/utils.py
get_output_strides_from_heads(head_configs)
¶
Get list of output strides from head configs.
Source code in sleap_nn/config/utils.py
oneof(attrs_cls, must_be_set=False)
¶
Ensure that the decorated attrs class only has a single attribute set.
This decorator is inspired by the oneof protobuffer field behavior.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attrs_cls
|
An attrs decorated class. |
required | |
must_be_set
|
bool
|
If True, raise an error if none of the attributes are set. If not, error will only be raised if more than one attribute is set. |
False
|
Returns:
| Type | Description |
|---|---|
|
The |
Source code in sleap_nn/config/utils.py
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 | |
resolve_auto_num_workers(data_pipeline_fw, train_labels=None, val_labels=None, memory_buffer=0.2, log=True)
¶
Pick a dataloader worker count for num_workers: "auto".
Workers are bounded by two independent limits, and auto takes the
smaller:
CPU. One core is left for the main/training process and the result is
capped at :data:MAX_AUTO_NUM_WORKERS, since dataloading here is dominated
by decode and cache lookup rather than heavy CPU transforms.
Memory. Under torch_dataset_cache_img_memory every worker adds a
share of the image cache (see
:func:sleap_nn.data.utils.worker_memory_overhead_factor — ~25% of it per
worker when forking on Linux, a full copy when spawning on macOS/Windows). Workers
are therefore a memory multiplier on exactly the pipeline that is already
the most memory-hungry, so auto inverts the same estimate
_setup_datasets uses and returns the largest count that still fits in
available RAM. Without this, auto could itself push a run past the
memory check and silently downgrade it to disk caching.
Two cases short-circuit:
torch_dataset(streaming) always resolves to0: it reads frames through the video backend inside the dataset, and those backends (e.g. openh5pyhandles) cannot be pickled to worker processes. This is the constraint documented ondata_config.data_pipeline_fw.- If the cache does not fit even at zero workers, the run will fall back to
disk caching anyway, where workers are cheap — so the CPU bound applies
rather than a pointless
0.
torch_dataset_cache_img_disk holds no large in-process cache, so it is
CPU-bound only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_pipeline_fw
|
str
|
The configured |
required |
train_labels
|
Optional[list]
|
Training labels, used to size the in-memory cache. When omitted, the memory bound is skipped and only the CPU bound applies. |
None
|
val_labels
|
Optional[list]
|
Validation labels, as above. |
None
|
memory_buffer
|
float
|
Fraction of memory reserved for training overhead, matching
the value |
0.2
|
log
|
bool
|
Whether to report when memory rather than CPU is the binding limit.
Set |
True
|
Returns:
| Type | Description |
|---|---|
int
|
The resolved worker count. |
Source code in sleap_nn/config/utils.py
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 | |
resolve_model_dir(model_path)
¶
Resolve a user-supplied model path to its model directory.
A trained model lives in a directory holding training_config.{yaml,json}
and a best.ckpt checkpoint. Callers historically had to pass that
directory. This helper additionally accepts a path to a file inside it —
either the training_config.{yaml,json} config or a .ckpt checkpoint —
and returns the containing directory, so users can point at best.ckpt or
training_config.yaml wherever a model directory is expected (issue #575).
The directory's contents are intentionally NOT validated here: the caller's
loader (e.g. :func:sleap_nn.inference.loaders._load_training_config) remains
the single source of truth for whether the resolved directory holds a usable
config and checkpoint, so its error messages stay attributable.
A directory is always loaded via its best.ckpt. If the path points at a
different checkpoint (e.g. last.ckpt), a warning is emitted and
best.ckpt is loaded anyway — use backbone_ckpt_path / head_ckpt_path
to load a specific checkpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_path
|
Union[str, Path]
|
A model directory, or a path to a |
required |
Returns:
| Type | Description |
|---|---|
str
|
The resolved model directory as a POSIX-style string. Relative paths are preserved (only the path separators are normalized); the path is not resolved against the filesystem root. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If |
Source code in sleap_nn/config/utils.py
suggest_num_workers(data_pipeline_fw, explicit, resolve)
¶
Hint that a cached run is leaving dataloading throughput on the table.
Caching (memory or disk) is what makes num_workers > 0 usable at all —
the streaming pipeline cannot fork its video backends — so a cached run left
at the default of 0 workers is decoding batches serially in the training
process for no reason. This nudges the user toward the worker count their
machine can actually support.
The suggested count is whatever num_workers: "auto" would pick here, not
a fixed "use 2-4": on the in-memory pipeline that number is already bounded
by the dataset's cache size and free RAM, so the hint can never talk a user
into a setting that would push their run past the memory check and downgrade
it to disk caching.
Silent when the pipeline is streaming, when every loader is already at or
above the suggestion, or when nothing could be suggested (auto resolves
to 0 on this machine).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_pipeline_fw
|
str
|
The configured |
required |
explicit
|
dict
|
Mapping of loader name to its explicitly-configured worker
count, i.e. the loaders that did not ask for |
required |
resolve
|
Zero-arg callable returning the resolved |
required |
Source code in sleap_nn/config/utils.py
usable_cpu_count()
¶
Return the number of CPUs actually usable by this process.
Prefers the process's CPU affinity mask over the machine's total core count,
so a run confined to a subset of cores (cgroups/cpusets, SLURM, Docker
--cpuset-cpus) sizes itself to its allocation instead of to the host.
Falls back to :func:os.cpu_count where affinity is unavailable (macOS,
Windows).
Returns:
| Type | Description |
|---|---|
int
|
The number of usable CPUs (at least 1). |