nnInteractive 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. nnInteractive/__init__.py +3 -0
  2. nnInteractive/inference/__init__.py +0 -0
  3. nnInteractive/inference/cvpr2025_challenge_baseline/__init__.py +0 -0
  4. nnInteractive/inference/cvpr2025_challenge_baseline/predict.py +173 -0
  5. nnInteractive/inference/inference_session.py +1400 -0
  6. nnInteractive/interaction/__init__.py +0 -0
  7. nnInteractive/interaction/point.py +166 -0
  8. nnInteractive/supervoxel/setup.py +4 -0
  9. nnInteractive/supervoxel/src/metadata.py +118 -0
  10. nnInteractive/supervoxel/src/reader.py +175 -0
  11. nnInteractive/supervoxel/src/run.py +136 -0
  12. nnInteractive/supervoxel/src/sam2/__init__.py +2 -0
  13. nnInteractive/supervoxel/src/sam2/sam2/__init__.py +11 -0
  14. nnInteractive/supervoxel/src/sam2/sam2/automatic_mask_generator.py +434 -0
  15. nnInteractive/supervoxel/src/sam2/sam2/benchmark.py +86 -0
  16. nnInteractive/supervoxel/src/sam2/sam2/build_sam.py +172 -0
  17. nnInteractive/supervoxel/src/sam2/sam2/modeling/__init__.py +5 -0
  18. nnInteractive/supervoxel/src/sam2/sam2/modeling/backbones/__init__.py +5 -0
  19. nnInteractive/supervoxel/src/sam2/sam2/modeling/backbones/hieradet.py +305 -0
  20. nnInteractive/supervoxel/src/sam2/sam2/modeling/backbones/image_encoder.py +132 -0
  21. nnInteractive/supervoxel/src/sam2/sam2/modeling/backbones/utils.py +89 -0
  22. nnInteractive/supervoxel/src/sam2/sam2/modeling/memory_attention.py +167 -0
  23. nnInteractive/supervoxel/src/sam2/sam2/modeling/memory_encoder.py +179 -0
  24. nnInteractive/supervoxel/src/sam2/sam2/modeling/position_encoding.py +217 -0
  25. nnInteractive/supervoxel/src/sam2/sam2/modeling/sam/__init__.py +5 -0
  26. nnInteractive/supervoxel/src/sam2/sam2/modeling/sam/mask_decoder.py +274 -0
  27. nnInteractive/supervoxel/src/sam2/sam2/modeling/sam/prompt_encoder.py +194 -0
  28. nnInteractive/supervoxel/src/sam2/sam2/modeling/sam/transformer.py +293 -0
  29. nnInteractive/supervoxel/src/sam2/sam2/modeling/sam2_base.py +879 -0
  30. nnInteractive/supervoxel/src/sam2/sam2/modeling/sam2_utils.py +315 -0
  31. nnInteractive/supervoxel/src/sam2/sam2/sam2_image_predictor.py +433 -0
  32. nnInteractive/supervoxel/src/sam2/sam2/sam2_video_predictor.py +1171 -0
  33. nnInteractive/supervoxel/src/sam2/sam2/sam2_video_predictor_legacy.py +1125 -0
  34. nnInteractive/supervoxel/src/sam2/sam2/utils/__init__.py +5 -0
  35. nnInteractive/supervoxel/src/sam2/sam2/utils/amg.py +332 -0
  36. nnInteractive/supervoxel/src/sam2/sam2/utils/misc.py +488 -0
  37. nnInteractive/supervoxel/src/sam2/sam2/utils/transforms.py +108 -0
  38. nnInteractive/supervoxel/src/sam2/setup.py +174 -0
  39. nnInteractive/supervoxel/src/sam2/training/__init__.py +5 -0
  40. nnInteractive/supervoxel/src/sam2/training/dataset/__init__.py +5 -0
  41. nnInteractive/supervoxel/src/sam2/training/dataset/sam2_datasets.py +176 -0
  42. nnInteractive/supervoxel/src/sam2/training/dataset/transforms.py +481 -0
  43. nnInteractive/supervoxel/src/sam2/training/dataset/utils.py +102 -0
  44. nnInteractive/supervoxel/src/sam2/training/dataset/vos_dataset.py +154 -0
  45. nnInteractive/supervoxel/src/sam2/training/dataset/vos_raw_dataset.py +290 -0
  46. nnInteractive/supervoxel/src/sam2/training/dataset/vos_sampler.py +103 -0
  47. nnInteractive/supervoxel/src/sam2/training/dataset/vos_segment_loader.py +289 -0
  48. nnInteractive/supervoxel/src/sam2/training/loss_fns.py +290 -0
  49. nnInteractive/supervoxel/src/sam2/training/model/__init__.py +5 -0
  50. nnInteractive/supervoxel/src/sam2/training/model/sam2.py +515 -0
  51. nnInteractive/supervoxel/src/sam2/training/optimizer.py +462 -0
  52. nnInteractive/supervoxel/src/sam2/training/scripts/sav_frame_extraction_submitit.py +157 -0
  53. nnInteractive/supervoxel/src/sam2/training/train.py +232 -0
  54. nnInteractive/supervoxel/src/sam2/training/trainer.py +1051 -0
  55. nnInteractive/supervoxel/src/sam2/training/utils/__init__.py +5 -0
  56. nnInteractive/supervoxel/src/sam2/training/utils/checkpoint_utils.py +328 -0
  57. nnInteractive/supervoxel/src/sam2/training/utils/data_utils.py +166 -0
  58. nnInteractive/supervoxel/src/sam2/training/utils/distributed.py +560 -0
  59. nnInteractive/supervoxel/src/sam2/training/utils/logger.py +236 -0
  60. nnInteractive/supervoxel/src/sam2/training/utils/train_utils.py +275 -0
  61. nnInteractive/supervoxel/src/supervoxel.py +198 -0
  62. nnInteractive/trainer/__init__.py +0 -0
  63. nnInteractive/trainer/nnInteractiveTrainer.py +24 -0
  64. nnInteractive/utils/__init__.py +0 -0
  65. nnInteractive/utils/bboxes.py +217 -0
  66. nnInteractive/utils/checkpoint_cleansing.py +9 -0
  67. nnInteractive/utils/crop.py +268 -0
  68. nnInteractive/utils/erosion_dilation.py +48 -0
  69. nnInteractive/utils/inference_helpers.py +45 -0
  70. nnInteractive/utils/os_shennanigans.py +16 -0
  71. nnInteractive/utils/rounding.py +13 -0
  72. nninteractive-2.0.0.dist-info/METADATA +511 -0
  73. nninteractive-2.0.0.dist-info/RECORD +76 -0
  74. nninteractive-2.0.0.dist-info/WHEEL +5 -0
  75. nninteractive-2.0.0.dist-info/licenses/LICENSE +201 -0
  76. nninteractive-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,174 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+
4
+ # This source code is licensed under the license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+ import os
7
+
8
+ from setuptools import find_packages, setup
9
+
10
+ # Package metadata
11
+ NAME = "SAM-2"
12
+ VERSION = "1.0"
13
+ DESCRIPTION = "SAM 2: Segment Anything in Images and Videos"
14
+ URL = "https://github.com/facebookresearch/sam2"
15
+ AUTHOR = "Meta AI"
16
+ AUTHOR_EMAIL = "segment-anything@meta.com"
17
+ LICENSE = "Apache 2.0"
18
+
19
+ # Read the contents of README file
20
+ with open("README.md", "r", encoding="utf-8") as f:
21
+ LONG_DESCRIPTION = f.read()
22
+
23
+ # Required dependencies
24
+ REQUIRED_PACKAGES = [
25
+ "torch>=2.5.1",
26
+ "torchvision>=0.20.1",
27
+ "numpy>=1.24.4",
28
+ "tqdm>=4.66.1",
29
+ "hydra-core>=1.3.2",
30
+ "iopath>=0.1.10",
31
+ "pillow>=9.4.0",
32
+ ]
33
+
34
+ EXTRA_PACKAGES = {
35
+ "notebooks": [
36
+ "matplotlib>=3.9.1",
37
+ "jupyter>=1.0.0",
38
+ "opencv-python>=4.7.0",
39
+ "eva-decord>=0.6.1",
40
+ ],
41
+ "interactive-demo": [
42
+ "Flask>=3.0.3",
43
+ "Flask-Cors>=5.0.0",
44
+ "av>=13.0.0",
45
+ "dataclasses-json>=0.6.7",
46
+ "eva-decord>=0.6.1",
47
+ "gunicorn>=23.0.0",
48
+ "imagesize>=1.4.1",
49
+ "pycocotools>=2.0.8",
50
+ "strawberry-graphql>=0.243.0",
51
+ ],
52
+ "dev": [
53
+ "black==24.2.0",
54
+ "usort==1.0.2",
55
+ "ufmt==2.0.0b2",
56
+ "fvcore>=0.1.5.post20221221",
57
+ "pandas>=2.2.2",
58
+ "scikit-image>=0.24.0",
59
+ "tensorboard>=2.17.0",
60
+ "pycocotools>=2.0.8",
61
+ "tensordict>=0.6.0",
62
+ "opencv-python>=4.7.0",
63
+ "submitit>=1.5.1",
64
+ ],
65
+ }
66
+
67
+ # By default, we also build the SAM 2 CUDA extension.
68
+ # You may turn off CUDA build with `export SAM2_BUILD_CUDA=0`.
69
+ BUILD_CUDA = os.getenv("SAM2_BUILD_CUDA", "1") == "1"
70
+ # By default, we allow SAM 2 installation to proceed even with build errors.
71
+ # You may force stopping on errors with `export SAM2_BUILD_ALLOW_ERRORS=0`.
72
+ BUILD_ALLOW_ERRORS = os.getenv("SAM2_BUILD_ALLOW_ERRORS", "1") == "1"
73
+
74
+ # Catch and skip errors during extension building and print a warning message
75
+ # (note that this message only shows up under verbose build mode
76
+ # "pip install -v -e ." or "python setup.py build_ext -v")
77
+ CUDA_ERROR_MSG = (
78
+ "{}\n\n"
79
+ "Failed to build the SAM 2 CUDA extension due to the error above. "
80
+ "You can still use SAM 2 and it's OK to ignore the error above, although some "
81
+ "post-processing functionality may be limited (which doesn't affect the results in most cases; "
82
+ "(see https://github.com/facebookresearch/sam2/blob/main/INSTALL.md).\n"
83
+ )
84
+
85
+
86
+ def get_extensions():
87
+ if not BUILD_CUDA:
88
+ return []
89
+
90
+ try:
91
+ from torch.utils.cpp_extension import CUDAExtension
92
+
93
+ srcs = ["sam2/csrc/connected_components.cu"]
94
+ compile_args = {
95
+ "cxx": [],
96
+ "nvcc": [
97
+ "-DCUDA_HAS_FP16=1",
98
+ "-D__CUDA_NO_HALF_OPERATORS__",
99
+ "-D__CUDA_NO_HALF_CONVERSIONS__",
100
+ "-D__CUDA_NO_HALF2_OPERATORS__",
101
+ ],
102
+ }
103
+ ext_modules = [CUDAExtension("sam2._C", srcs, extra_compile_args=compile_args)]
104
+ except Exception as e:
105
+ if BUILD_ALLOW_ERRORS:
106
+ print(CUDA_ERROR_MSG.format(e))
107
+ ext_modules = []
108
+ else:
109
+ raise e
110
+
111
+ return ext_modules
112
+
113
+
114
+ try:
115
+ from torch.utils.cpp_extension import BuildExtension
116
+
117
+ class BuildExtensionIgnoreErrors(BuildExtension):
118
+
119
+ def finalize_options(self):
120
+ try:
121
+ super().finalize_options()
122
+ except Exception as e:
123
+ print(CUDA_ERROR_MSG.format(e))
124
+ self.extensions = []
125
+
126
+ def build_extensions(self):
127
+ try:
128
+ super().build_extensions()
129
+ except Exception as e:
130
+ print(CUDA_ERROR_MSG.format(e))
131
+ self.extensions = []
132
+
133
+ def get_ext_filename(self, ext_name):
134
+ try:
135
+ return super().get_ext_filename(ext_name)
136
+ except Exception as e:
137
+ print(CUDA_ERROR_MSG.format(e))
138
+ self.extensions = []
139
+ return "_C.so"
140
+
141
+ cmdclass = {
142
+ "build_ext": (
143
+ BuildExtensionIgnoreErrors.with_options(no_python_abi_suffix=True)
144
+ if BUILD_ALLOW_ERRORS
145
+ else BuildExtension.with_options(no_python_abi_suffix=True)
146
+ )
147
+ }
148
+ except Exception as e:
149
+ cmdclass = {}
150
+ if BUILD_ALLOW_ERRORS:
151
+ print(CUDA_ERROR_MSG.format(e))
152
+ else:
153
+ raise e
154
+
155
+
156
+ # Setup configuration
157
+ setup(
158
+ name=NAME,
159
+ version=VERSION,
160
+ description=DESCRIPTION,
161
+ long_description=LONG_DESCRIPTION,
162
+ long_description_content_type="text/markdown",
163
+ url=URL,
164
+ author=AUTHOR,
165
+ author_email=AUTHOR_EMAIL,
166
+ license=LICENSE,
167
+ packages=find_packages(exclude="notebooks"),
168
+ include_package_data=True,
169
+ install_requires=REQUIRED_PACKAGES,
170
+ extras_require=EXTRA_PACKAGES,
171
+ python_requires=">=3.10.0",
172
+ ext_modules=get_extensions(),
173
+ cmdclass=cmdclass,
174
+ )
@@ -0,0 +1,5 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+
4
+ # This source code is licensed under the license found in the
5
+ # LICENSE file in the root directory of this source tree.
@@ -0,0 +1,5 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+
4
+ # This source code is licensed under the license found in the
5
+ # LICENSE file in the root directory of this source tree.
@@ -0,0 +1,176 @@
1
+ # Copyright (c) Meta Platforms, Inc. and affiliates.
2
+ # All rights reserved.
3
+
4
+ # This source code is licensed under the license found in the
5
+ # LICENSE file in the root directory of this source tree.
6
+
7
+ import logging
8
+ import math
9
+ from typing import Callable, Iterable, List, Optional, Sequence
10
+
11
+ import torch
12
+
13
+ from torch.utils.data import BatchSampler, DataLoader, Dataset, IterableDataset, Subset
14
+
15
+ from torch.utils.data.distributed import DistributedSampler
16
+
17
+
18
+ class MixedDataLoader:
19
+ def __init__(self, dataloaders: List[DataLoader], mixing_prob: torch.FloatTensor):
20
+ """
21
+ Args:
22
+ dataloaders (List[DataLoader]): List of DataLoaders to be mixed.
23
+ mixing_prob (torch.FloatTensor): Probability of each dataloader to be sampled from
24
+
25
+ """
26
+ assert len(dataloaders) == mixing_prob.shape[0]
27
+ self.dataloaders = dataloaders
28
+ self.mixing_prob = mixing_prob
29
+ # Iterator state
30
+ self._iter_dls = None
31
+ self._iter_mixing_prob = None
32
+ self.random_generator = torch.Generator()
33
+
34
+ def __len__(self):
35
+ return sum([len(d) for d in self.dataloaders])
36
+
37
+ def __iter__(self):
38
+ # Synchronize dataloader seeds
39
+ self.random_generator.manual_seed(42)
40
+ self._iter_dls = [iter(loader) for loader in self.dataloaders]
41
+ self._iter_mixing_prob = self.mixing_prob.clone()
42
+ return self
43
+
44
+ def __next__(self):
45
+ """
46
+ Sample a dataloader to sample from based on mixing probabilities. If one of the dataloaders is exhausted, we continue sampling from the other loaders until all are exhausted.
47
+ """
48
+ if self._iter_dls is None:
49
+ raise TypeError(f"{type(self).__name__} object is not an iterator")
50
+
51
+ while self._iter_mixing_prob.any(): # at least one D-Loader with non-zero prob.
52
+ dataset_idx = self._iter_mixing_prob.multinomial(1, generator=self.random_generator).item()
53
+ try:
54
+ item = next(self._iter_dls[dataset_idx])
55
+ return item
56
+ except StopIteration:
57
+ # No more iterations for this dataset, set it's mixing probability to zero and try again.
58
+ self._iter_mixing_prob[dataset_idx] = 0
59
+ except Exception as e:
60
+ # log and raise any other unexpected error.
61
+ logging.error(e)
62
+ raise e
63
+
64
+ # Exhausted all iterators
65
+ raise StopIteration
66
+
67
+
68
+ class TorchTrainMixedDataset:
69
+ def __init__(
70
+ self,
71
+ datasets: List[Dataset],
72
+ batch_sizes: List[int],
73
+ num_workers: int,
74
+ shuffle: bool,
75
+ pin_memory: bool,
76
+ drop_last: bool,
77
+ collate_fn: Optional[Callable] = None,
78
+ worker_init_fn: Optional[Callable] = None,
79
+ phases_per_epoch: int = 1,
80
+ dataset_prob: Optional[List[float]] = None,
81
+ ) -> None:
82
+ """
83
+ Args:
84
+ datasets (List[Dataset]): List of Datasets to be mixed.
85
+ batch_sizes (List[int]): Batch sizes for each dataset in the list.
86
+ num_workers (int): Number of workers per dataloader.
87
+ shuffle (bool): Whether or not to shuffle data.
88
+ pin_memory (bool): If True, use pinned memory when loading tensors from disk.
89
+ drop_last (bool): Whether or not to drop the last batch of data.
90
+ collate_fn (Callable): Function to merge a list of samples into a mini-batch.
91
+ worker_init_fn (Callable): Function to init each dataloader worker.
92
+ phases_per_epoch (int): Number of phases per epoch.
93
+ dataset_prob (List[float]): Probability of choosing the dataloader to sample from. Should sum to 1.0
94
+ """
95
+
96
+ self.datasets = datasets
97
+ self.batch_sizes = batch_sizes
98
+ self.num_workers = num_workers
99
+ self.shuffle = shuffle
100
+ self.pin_memory = pin_memory
101
+ self.drop_last = drop_last
102
+ self.collate_fn = collate_fn
103
+ self.worker_init_fn = worker_init_fn
104
+ assert len(self.datasets) > 0
105
+ for dataset in self.datasets:
106
+ assert not isinstance(dataset, IterableDataset), "Not supported"
107
+ # `RepeatFactorWrapper` requires calling set_epoch first to get its length
108
+ self._set_dataset_epoch(dataset, 0)
109
+ self.phases_per_epoch = phases_per_epoch
110
+ self.chunks = [None] * len(datasets)
111
+ if dataset_prob is None:
112
+ # If not provided, assign each dataset a probability proportional to its length.
113
+ dataset_lens = [
114
+ (math.floor(len(d) / bs) if drop_last else math.ceil(len(d) / bs))
115
+ for d, bs in zip(datasets, batch_sizes)
116
+ ]
117
+ total_len = sum(dataset_lens)
118
+ dataset_prob = torch.tensor([d_len / total_len for d_len in dataset_lens])
119
+ else:
120
+ assert len(dataset_prob) == len(datasets)
121
+ dataset_prob = torch.tensor(dataset_prob)
122
+
123
+ logging.info(f"Dataset mixing probabilities: {dataset_prob.tolist()}")
124
+ assert dataset_prob.sum().item() == 1.0, "Probabilities should sum to 1.0"
125
+ self.dataset_prob = dataset_prob
126
+
127
+ def _set_dataset_epoch(self, dataset, epoch: int) -> None:
128
+ if hasattr(dataset, "epoch"):
129
+ dataset.epoch = epoch
130
+ if hasattr(dataset, "set_epoch"):
131
+ dataset.set_epoch(epoch)
132
+
133
+ def get_loader(self, epoch) -> Iterable:
134
+ dataloaders = []
135
+ for d_idx, (dataset, batch_size) in enumerate(zip(self.datasets, self.batch_sizes)):
136
+ if self.phases_per_epoch > 1:
137
+ # Major epoch that looops over entire dataset
138
+ # len(main_epoch) == phases_per_epoch * len(epoch)
139
+ main_epoch = epoch // self.phases_per_epoch
140
+
141
+ # Phase with in the main epoch
142
+ local_phase = epoch % self.phases_per_epoch
143
+
144
+ # Start of new data-epoch or job is resumed after preemtion.
145
+ if local_phase == 0 or self.chunks[d_idx] is None:
146
+ # set seed for dataset epoch
147
+ # If using RepeatFactorWrapper, this step currectly re-samples indices before chunking.
148
+ self._set_dataset_epoch(dataset, main_epoch)
149
+
150
+ # Separate random generator for subset sampling
151
+ g = torch.Generator()
152
+ g.manual_seed(main_epoch)
153
+ self.chunks[d_idx] = torch.chunk(
154
+ torch.randperm(len(dataset), generator=g),
155
+ self.phases_per_epoch,
156
+ )
157
+
158
+ dataset = Subset(dataset, self.chunks[d_idx][local_phase])
159
+ else:
160
+ self._set_dataset_epoch(dataset, epoch)
161
+
162
+ sampler = DistributedSampler(dataset, shuffle=self.shuffle)
163
+ sampler.set_epoch(epoch)
164
+
165
+ batch_sampler = BatchSampler(sampler, batch_size, drop_last=self.drop_last)
166
+ dataloaders.append(
167
+ DataLoader(
168
+ dataset,
169
+ num_workers=self.num_workers,
170
+ pin_memory=self.pin_memory,
171
+ batch_sampler=batch_sampler,
172
+ collate_fn=self.collate_fn,
173
+ worker_init_fn=self.worker_init_fn,
174
+ )
175
+ )
176
+ return MixedDataLoader(dataloaders, self.dataset_prob)