Skip to content

Commit 4a4f436

Browse files
committed
Apply repository Python formatting
Signed-off-by: Piotr Żelasko <pzelasko@nvidia.com>
1 parent 95a77c3 commit 4a4f436

8 files changed

Lines changed: 89 additions & 294 deletions

File tree

nemo/collections/common/data/lhotse/audio_token_estimator.py

Lines changed: 17 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -40,35 +40,22 @@ def from_config(cls, config: Mapping[str, Any]) -> ConvSubsamplingSpec:
4040
required = {"kernel_size", "stride", "padding"}
4141
missing = required - set(config)
4242
if missing:
43-
raise ValueError(
44-
f"audio_token_estimator.subsampling is missing: {sorted(missing)}"
45-
)
43+
raise ValueError(f"audio_token_estimator.subsampling is missing: {sorted(missing)}")
4644
ans = cls(
4745
kernel_size=int(config["kernel_size"]),
4846
stride=int(config["stride"]),
4947
padding=int(config["padding"]),
5048
repeat=int(config.get("repeat", 1)),
5149
ceil_mode=bool(config.get("ceil_mode", False)),
5250
)
53-
if (
54-
ans.kernel_size <= 0
55-
or ans.stride <= 0
56-
or ans.padding < 0
57-
or ans.repeat <= 0
58-
):
59-
raise ValueError(
60-
f"Invalid audio_token_estimator.subsampling values: {config}"
61-
)
51+
if ans.kernel_size <= 0 or ans.stride <= 0 or ans.padding < 0 or ans.repeat <= 0:
52+
raise ValueError(f"Invalid audio_token_estimator.subsampling values: {config}")
6253
return ans
6354

6455
def __call__(self, length: int) -> int:
6556
for _ in range(self.repeat):
6657
numerator = length + 2 * self.padding - self.kernel_size
67-
quotient = (
68-
-(-numerator // self.stride)
69-
if self.ceil_mode
70-
else numerator // self.stride
71-
)
58+
quotient = -(-numerator // self.stride) if self.ceil_mode else numerator // self.stride
7259
length = quotient + 1
7360
return length
7461

@@ -85,9 +72,7 @@ def from_config(cls, config: Mapping[str, Any]) -> FeatureStackingSubsamplingSpe
8572
raise ValueError("audio_token_estimator.subsampling is missing: ['factor']")
8673
ans = cls(factor=int(config["factor"]))
8774
if ans.factor <= 0:
88-
raise ValueError(
89-
f"Invalid audio_token_estimator.subsampling values: {config}"
90-
)
75+
raise ValueError(f"Invalid audio_token_estimator.subsampling values: {config}")
9176
return ans
9277

9378
def __call__(self, length: int) -> int:
@@ -100,17 +85,15 @@ def __call__(self, length: int) -> int:
10085
def _subsampling_spec_from_config(config: Mapping[str, Any]) -> SubsamplingSpec:
10186
if not isinstance(config, Mapping):
10287
raise TypeError(
103-
"Each audio_token_estimator.subsampling stage must be a mapping, "
104-
f"got {type(config).__name__}"
88+
"Each audio_token_estimator.subsampling stage must be a mapping, " f"got {type(config).__name__}"
10589
)
10690
stage_type = config.get("type", "conv")
10791
if stage_type == "conv":
10892
return ConvSubsamplingSpec.from_config(config)
10993
if stage_type == "feature_stacking":
11094
return FeatureStackingSubsamplingSpec.from_config(config)
11195
raise ValueError(
112-
"audio_token_estimator.subsampling.type must be 'conv' or "
113-
f"'feature_stacking', got {stage_type!r}"
96+
"audio_token_estimator.subsampling.type must be 'conv' or " f"'feature_stacking', got {stage_type!r}"
11497
)
11598

11699

@@ -152,30 +135,20 @@ def from_config(
152135
required = {"n_fft", "hop_length", "stft_pad_amount"}
153136
missing = required - set(preprocessor)
154137
if missing:
155-
raise ValueError(
156-
f"audio_token_estimator.preprocessor is missing: {sorted(missing)}"
157-
)
138+
raise ValueError(f"audio_token_estimator.preprocessor is missing: {sorted(missing)}")
158139

159140
raw_subsampling = config.get("subsampling")
160141
if isinstance(raw_subsampling, Mapping):
161142
raw_subsampling = [raw_subsampling]
162-
if not isinstance(raw_subsampling, Sequence) or isinstance(
163-
raw_subsampling, (str, bytes)
164-
):
165-
raise TypeError(
166-
"audio_token_estimator.subsampling must be a mapping or list of mappings"
167-
)
168-
subsampling = tuple(
169-
_subsampling_spec_from_config(stage) for stage in raw_subsampling
170-
)
143+
if not isinstance(raw_subsampling, Sequence) or isinstance(raw_subsampling, (str, bytes)):
144+
raise TypeError("audio_token_estimator.subsampling must be a mapping or list of mappings")
145+
subsampling = tuple(_subsampling_spec_from_config(stage) for stage in raw_subsampling)
171146

172147
chunk_size_seconds = config.get("chunk_size_seconds")
173148
if chunk_size_seconds is not None:
174149
chunk_size_seconds = float(chunk_size_seconds)
175150
if chunk_size_seconds <= 0:
176-
raise ValueError(
177-
"audio_token_estimator.chunk_size_seconds must be positive or null"
178-
)
151+
raise ValueError("audio_token_estimator.chunk_size_seconds must be positive or null")
179152

180153
ans = cls(
181154
sample_rate=int(sample_rate),
@@ -185,15 +158,8 @@ def from_config(
185158
subsampling=subsampling,
186159
chunk_size_seconds=chunk_size_seconds,
187160
)
188-
if (
189-
ans.sample_rate <= 0
190-
or ans.n_fft <= 0
191-
or ans.hop_length <= 0
192-
or ans.stft_pad_amount < 0
193-
):
194-
raise ValueError(
195-
f"Invalid audio_token_estimator.preprocessor values: {preprocessor}"
196-
)
161+
if ans.sample_rate <= 0 or ans.n_fft <= 0 or ans.hop_length <= 0 or ans.stft_pad_amount < 0:
162+
raise ValueError(f"Invalid audio_token_estimator.preprocessor values: {preprocessor}")
197163
return ans
198164

199165
def estimate_cut(self, cut: Cut) -> int:
@@ -214,20 +180,15 @@ def estimate_samples(self, num_samples: int) -> int:
214180
if chunk_size is None or num_samples <= chunk_size:
215181
return self._estimate_single_pass(num_samples)
216182

217-
spans = [
218-
(begin, min(begin + chunk_size, num_samples))
219-
for begin in range(0, num_samples, chunk_size)
220-
]
183+
spans = [(begin, min(begin + chunk_size, num_samples)) for begin in range(0, num_samples, chunk_size)]
221184
min_chunk_size = self._min_chunk_size_samples()
222185
if len(spans) > 1 and spans[-1][1] - spans[-1][0] < min_chunk_size:
223186
spans[-2] = (spans[-2][0], spans[-1][1])
224187
spans.pop()
225188
return sum(self._estimate_single_pass(end - begin) for begin, end in spans)
226189

227190
def _estimate_single_pass(self, num_samples: int) -> int:
228-
length = (
229-
num_samples + 2 * self.stft_pad_amount - self.n_fft
230-
) // self.hop_length
191+
length = (num_samples + 2 * self.stft_pad_amount - self.n_fft) // self.hop_length
231192
for stage in self.subsampling:
232193
length = stage(length)
233194
return max(1, length)
@@ -242,9 +203,7 @@ def _min_chunk_size_samples(self) -> int:
242203
# find the first hop-aligned waveform producing at least two feature frames.
243204
samples = self.hop_length
244205
for _ in range(16):
245-
feature_frames = (
246-
samples + 2 * self.stft_pad_amount - self.n_fft
247-
) // self.hop_length
206+
feature_frames = (samples + 2 * self.stft_pad_amount - self.n_fft) // self.hop_length
248207
if feature_frames >= 2:
249208
return samples
250209
samples += self.hop_length

nemo/collections/common/data/lhotse/dataloader.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,13 @@
4343
from lhotse.utils import fix_random_seed
4444
from omegaconf import DictConfig, OmegaConf
4545

46-
from nemo.collections.common.data.lhotse.audio_token_estimator import (
47-
AudioTokenEstimator,
48-
)
46+
from nemo.collections.common.data.lhotse.audio_token_estimator import AudioTokenEstimator
4947
from nemo.collections.common.data.lhotse.cutset import (
5048
IncompleteConfigError,
5149
guess_parse_cutset,
5250
read_cutset_from_config,
5351
)
54-
from nemo.collections.common.data.lhotse.packed_sequence_sampler import (
55-
PackedSequenceDynamicCutSampler,
56-
)
52+
from nemo.collections.common.data.lhotse.packed_sequence_sampler import PackedSequenceDynamicCutSampler
5753
from nemo.collections.common.data.lhotse.sampling import (
5854
BucketingFilter,
5955
CERFilter,
@@ -980,11 +976,7 @@ def get_lhotse_sampler_from_config(config, global_rank, world_size, tokenizer=No
980976
f"Creating a Lhotse DynamicCutSampler (bucketing is disabled, "
981977
f"(max_batch_duration={config.batch_duration} max_batch_size={config.batch_size})"
982978
)
983-
sampler_cls = (
984-
PackedSequenceDynamicCutSampler
985-
if config.use_packed_sequence_sampling
986-
else DynamicCutSampler
987-
)
979+
sampler_cls = PackedSequenceDynamicCutSampler if config.use_packed_sequence_sampling else DynamicCutSampler
988980
sampler = sampler_cls(
989981
cuts,
990982
constraint=constraint,

nemo/collections/common/data/lhotse/packed_sequence_sampler.py

Lines changed: 22 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,13 @@
1515
from collections.abc import Sequence
1616
from typing import Any
1717

18+
from lhotse import CutSet
1819
from lhotse.dataset import DynamicCutSampler
1920
from lhotse.dataset.sampling.dynamic import DurationBatcher, Filter
2021
from lhotse.lazy import get_graph_origin, resolve_iterator_source
2122

22-
from lhotse import CutSet
23-
2423

25-
def _select_best_fit_indices(
26-
lengths: Sequence[int], capacity: int, max_items: int | None = None
27-
) -> list[int]:
24+
def _select_best_fit_indices(lengths: Sequence[int], capacity: int, max_items: int | None = None) -> list[int]:
2825
"""Select an exact best-fit subset, preferring earlier items on ties."""
2926
if capacity < 0:
3027
raise ValueError(f"capacity must be non-negative (got {capacity})")
@@ -91,8 +88,7 @@ def __init__(self, *args, packing_buffer_size: int, **kwargs):
9188
super().__init__(*args, **kwargs)
9289
if packing_buffer_size <= 0:
9390
raise ValueError(
94-
"shuffle_buffer_size must be a positive packing-buffer size "
95-
f"(got {packing_buffer_size})"
91+
"shuffle_buffer_size must be a positive packing-buffer size " f"(got {packing_buffer_size})"
9692
)
9793
self.packing_buffer_size = packing_buffer_size
9894
self._source_exhausted = False
@@ -108,32 +104,20 @@ def _detuplify(examples):
108104

109105
@staticmethod
110106
def _measured_example(example_or_tuple):
111-
return (
112-
example_or_tuple[0]
113-
if isinstance(example_or_tuple, tuple)
114-
else example_or_tuple
115-
)
107+
return example_or_tuple[0] if isinstance(example_or_tuple, tuple) else example_or_tuple
116108

117109
def _fill_packing_buffer(self) -> None:
118-
while (
119-
len(self.reuse_cuts_buffer) < self.packing_buffer_size
120-
and not self._source_exhausted
121-
):
110+
while len(self.reuse_cuts_buffer) < self.packing_buffer_size and not self._source_exhausted:
122111
try:
123112
self.reuse_cuts_buffer.append(next(self.cuts_iter))
124113
except StopIteration:
125114
self._source_exhausted = True
126115

127116
def _measure_integer_length(self, example_or_tuple) -> int:
128-
length = self.constraint.measure_length(
129-
self._measured_example(example_or_tuple)
130-
)
117+
length = self.constraint.measure_length(self._measured_example(example_or_tuple))
131118
integer_length = int(length)
132119
if integer_length != length:
133-
raise ValueError(
134-
"Packed sequence sampling requires integer token lengths, "
135-
f"but measured {length!r}."
136-
)
120+
raise ValueError("Packed sequence sampling requires integer token lengths, " f"but measured {length!r}.")
137121
return integer_length
138122

139123
def _limits(self) -> tuple[int, int | None]:
@@ -144,18 +128,14 @@ def _limits(self) -> tuple[int, int | None]:
144128
max_tokens = getattr(internal, "max_tokens", None)
145129
max_examples = getattr(internal, "max_examples", max_examples)
146130
if max_tokens is None:
147-
raise ValueError(
148-
"Packed sequence sampling requires batch_tokens to define the exact token cap."
149-
)
131+
raise ValueError("Packed sequence sampling requires batch_tokens to define the exact token cap.")
150132
max_tokens = int(max_tokens)
151133
if max_tokens <= 0:
152134
raise ValueError(f"batch_tokens must be positive (got {max_tokens})")
153135
if max_examples is not None:
154136
max_examples = int(max_examples)
155137
if max_examples <= 0:
156-
raise ValueError(
157-
f"batch_size must be positive or null (got {max_examples})"
158-
)
138+
raise ValueError(f"batch_size must be positive or null (got {max_examples})")
159139
return max_tokens, max_examples
160140

161141
def _discard(self, examples) -> None:
@@ -182,35 +162,21 @@ def _collect_batch(self):
182162
)
183163

184164
remaining_items = None if max_examples is None else max_examples - 1
185-
tail_indices = _select_best_fit_indices(
186-
lengths[1:], max_tokens - anchor_length, max_items=remaining_items
187-
)
165+
tail_indices = _select_best_fit_indices(lengths[1:], max_tokens - anchor_length, max_items=remaining_items)
188166
selected_indices = {0, *(index + 1 for index in tail_indices)}
189-
examples = [
190-
example for index, example in enumerate(pool) if index in selected_indices
191-
]
192-
deferred = [
193-
example
194-
for index, example in enumerate(pool)
195-
if index not in selected_indices
196-
]
167+
examples = [example for index, example in enumerate(pool) if index in selected_indices]
168+
deferred = [example for index, example in enumerate(pool) if index not in selected_indices]
197169
self.reuse_cuts_buffer.clear()
198170
self.reuse_cuts_buffer.extend(deferred)
199171

200172
self.constraint.reset()
201173
for example in examples:
202174
self.constraint.add(self._measured_example(example))
203175
if self.constraint.exceeded():
204-
raise AssertionError(
205-
"Best-fit packed batch exceeded its configured constraint."
206-
)
176+
raise AssertionError("Best-fit packed batch exceeded its configured constraint.")
207177

208178
is_final_batch = self._source_exhausted and not self.reuse_cuts_buffer
209-
if (
210-
is_final_batch
211-
and self.drop_last
212-
and not self.constraint.close_to_exceeding()
213-
):
179+
if is_final_batch and self.drop_last and not self.constraint.close_to_exceeding():
214180
self._discard(examples)
215181
raise StopIteration()
216182

@@ -234,8 +200,7 @@ def __init__(
234200
):
235201
if shuffle_buffer_size is None or shuffle_buffer_size <= 0:
236202
raise ValueError(
237-
"shuffle_buffer_size must be a positive packing-buffer size "
238-
f"(got {shuffle_buffer_size})"
203+
"shuffle_buffer_size must be a positive packing-buffer size " f"(got {shuffle_buffer_size})"
239204
)
240205
# Consume the public `shuffle` argument for config compatibility, but
241206
# do not allocate DynamicCutSampler's second, reservoir-style buffer.
@@ -252,19 +217,13 @@ def __init__(
252217
self._inject_restored_packing_buffer = False
253218

254219
def _uses_indexed_restore(self) -> bool:
255-
return bool(self.cuts) and all(
256-
getattr(source, "has_constant_time_access", False) for source in self.cuts
257-
)
220+
return bool(self.cuts) and all(getattr(source, "has_constant_time_access", False) for source in self.cuts)
258221

259222
@staticmethod
260223
def _capture_packing_buffer_tokens(buffer) -> list[tuple[Any, ...]]:
261224
saved = []
262225
for example_or_tuple in buffer:
263-
examples = (
264-
example_or_tuple
265-
if isinstance(example_or_tuple, tuple)
266-
else (example_or_tuple,)
267-
)
226+
examples = example_or_tuple if isinstance(example_or_tuple, tuple) else (example_or_tuple,)
268227
tokens = tuple(get_graph_origin(example) for example in examples)
269228
if any(token is None for token in tokens):
270229
raise RuntimeError(
@@ -278,13 +237,9 @@ def state_dict(self) -> dict[str, Any]:
278237
state = super().state_dict()
279238
if self._uses_indexed_restore():
280239
if self._batcher is not None:
281-
state["packing_buffer_tokens"] = self._capture_packing_buffer_tokens(
282-
self._batcher.reuse_cuts_buffer
283-
)
240+
state["packing_buffer_tokens"] = self._capture_packing_buffer_tokens(self._batcher.reuse_cuts_buffer)
284241
else:
285-
state["packing_buffer_tokens"] = list(
286-
self._restored_packing_buffer_tokens
287-
)
242+
state["packing_buffer_tokens"] = list(self._restored_packing_buffer_tokens)
288243
else:
289244
# Replay restoration deterministically rebuilds the post-filter pool.
290245
state["packing_buffer_tokens"] = None
@@ -329,25 +284,18 @@ def _restore_packing_buffer(self) -> list[tuple[Any, ...]]:
329284
f"{len(tokens)} != {len(active_sources)}."
330285
)
331286
restored.append(
332-
tuple(
333-
resolve_iterator_source(source)[token]
334-
for source, token in zip(active_sources, tokens)
335-
)
287+
tuple(resolve_iterator_source(source)[token] for source, token in zip(active_sources, tokens))
336288
)
337289
restored.extend(self._restored_legacy_examples)
338290
return restored
339291

340292
def _initialize_epoch_iterator(self, *, rebuild_sources: bool) -> None:
341293
if rebuild_sources or self._active_cuts is None:
342294
self._active_cuts = self._make_epoch_sources()
343-
source_iterators = [
344-
iter(resolve_iterator_source(source)) for source in self._active_cuts
345-
]
295+
source_iterators = [iter(resolve_iterator_source(source)) for source in self._active_cuts]
346296
filtered_examples = Filter(
347297
iterator=zip(*source_iterators),
348-
predicate=lambda examples: all(
349-
self._filter_fn(example) for example in examples
350-
),
298+
predicate=lambda examples: all(self._filter_fn(example) for example in examples),
351299
diagnostics=self.diagnostics,
352300
)
353301
self._batcher = ExactTokenBatcher(

0 commit comments

Comments
 (0)