returnn 1.20250421.5132__py3-none-any.whl → 1.20250423.105638__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.
Potentially problematic release.
This version of returnn might be problematic. Click here for more details.
- returnn/PKG-INFO +1 -1
- returnn/_setup_info_generated.py +2 -2
- returnn/datasets/basic.py +3 -1
- returnn/datasets/util/vocabulary.py +20 -0
- returnn/torch/engine.py +34 -4
- returnn/util/basic.py +39 -28
- returnn/util/file_cache.py +101 -42
- {returnn-1.20250421.5132.dist-info → returnn-1.20250423.105638.dist-info}/METADATA +1 -1
- {returnn-1.20250421.5132.dist-info → returnn-1.20250423.105638.dist-info}/RECORD +12 -12
- {returnn-1.20250421.5132.dist-info → returnn-1.20250423.105638.dist-info}/LICENSE +0 -0
- {returnn-1.20250421.5132.dist-info → returnn-1.20250423.105638.dist-info}/WHEEL +0 -0
- {returnn-1.20250421.5132.dist-info → returnn-1.20250423.105638.dist-info}/top_level.txt +0 -0
returnn/PKG-INFO
CHANGED
returnn/_setup_info_generated.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
version = '1.
|
|
2
|
-
long_version = '1.
|
|
1
|
+
version = '1.20250423.105638'
|
|
2
|
+
long_version = '1.20250423.105638+git.767de47'
|
returnn/datasets/basic.py
CHANGED
|
@@ -1116,7 +1116,9 @@ class Dataset:
|
|
|
1116
1116
|
|
|
1117
1117
|
def serialize_data(self, key: str, data: numpy.ndarray) -> str:
|
|
1118
1118
|
"""
|
|
1119
|
-
|
|
1119
|
+
This is deprecated, as this is slow!
|
|
1120
|
+
In case you have a :class:`Vocabulary`, just use :func:`Vocabulary.get_seq_labels`
|
|
1121
|
+
or :func:`Vocabulary.serialize_labels`.
|
|
1120
1122
|
|
|
1121
1123
|
:param key: e.g. "classes". self.labels[key] should be set
|
|
1122
1124
|
:param numpy.ndarray data: 0D or 1D
|
|
@@ -339,6 +339,26 @@ class Vocabulary:
|
|
|
339
339
|
labels = self.labels
|
|
340
340
|
return " ".join(map(labels.__getitem__, seq))
|
|
341
341
|
|
|
342
|
+
def serialize_labels(self, data: numpy.ndarray) -> str:
|
|
343
|
+
"""
|
|
344
|
+
Like :func:`get_seq_labels` but a bit more generic, to not just work on sequences,
|
|
345
|
+
but any shape.
|
|
346
|
+
|
|
347
|
+
Also like :func:`Dataset.serialize_data` but even slightly more generic.
|
|
348
|
+
"""
|
|
349
|
+
if data.ndim == 0:
|
|
350
|
+
return self.id_to_label(data.item())
|
|
351
|
+
if data.ndim == 1:
|
|
352
|
+
return self.get_seq_labels(data)
|
|
353
|
+
|
|
354
|
+
def _s(d_: numpy.ndarray) -> str:
|
|
355
|
+
assert d_.ndim >= 1
|
|
356
|
+
if d_.ndim == 1:
|
|
357
|
+
return ",".join(self._labels[i] for i in d_)
|
|
358
|
+
return ",".join(f"[{_s(d_[t])}]" for t in range(d_.shape[0]))
|
|
359
|
+
|
|
360
|
+
return _s(data)
|
|
361
|
+
|
|
342
362
|
|
|
343
363
|
class BytePairEncoding(Vocabulary):
|
|
344
364
|
"""
|
returnn/torch/engine.py
CHANGED
|
@@ -82,15 +82,17 @@ class Engine(EngineBase):
|
|
|
82
82
|
) # type: Union[int,float,Dict[str,int],NumbersDict]
|
|
83
83
|
self._orig_model = None # type: Optional[Union[rf.Module, torch.nn.Module]]
|
|
84
84
|
self._pt_model = None # type: Optional[torch.nn.Module]
|
|
85
|
-
self.
|
|
86
|
-
self.
|
|
87
|
-
self.
|
|
85
|
+
self._epoch_start_func: Optional[Callable] = self.config.typed_value("epoch_start")
|
|
86
|
+
self._epoch_end_func: Optional[Callable] = self.config.typed_value("epoch_end")
|
|
87
|
+
self._train_step_func: Optional[Callable] = None
|
|
88
|
+
self._forward_step_func: Optional[Callable] = self.config.typed_value("forward_step")
|
|
89
|
+
self._forward_step_expected_outputs: Optional[TensorDict] = None
|
|
88
90
|
if self.config.typed_value("model_outputs") is not None:
|
|
89
91
|
self._forward_step_expected_outputs = TensorDict()
|
|
90
92
|
self._forward_step_expected_outputs.update(self.config.typed_value("model_outputs"), auto_convert=True)
|
|
91
93
|
self._save_model_epoch_interval = 1
|
|
92
94
|
self._ignore_param_set: Set[str] = set() # for the updater and for saving the model checkpoint
|
|
93
|
-
self._updater
|
|
95
|
+
self._updater: Optional[Updater] = None
|
|
94
96
|
|
|
95
97
|
self._use_autocast = False
|
|
96
98
|
self._autocast_dtype = None # type: Optional[str]
|
|
@@ -319,6 +321,26 @@ class Engine(EngineBase):
|
|
|
319
321
|
]
|
|
320
322
|
print(f"Memory usage ({self._device}):", " ".join(stats), file=log.v1)
|
|
321
323
|
|
|
324
|
+
def _on_epoch_start(self, *, dataset_name: str):
|
|
325
|
+
if self._epoch_start_func:
|
|
326
|
+
self._epoch_start_func(
|
|
327
|
+
epoch=self.epoch,
|
|
328
|
+
step=self.global_train_step,
|
|
329
|
+
model=self._orig_model,
|
|
330
|
+
dataset_name=dataset_name,
|
|
331
|
+
**util.get_fwd_compat_kwargs(),
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
def _on_epoch_end(self, *, dataset_name: str):
|
|
335
|
+
if self._epoch_end_func:
|
|
336
|
+
self._epoch_end_func(
|
|
337
|
+
epoch=self.epoch,
|
|
338
|
+
step=self.global_train_step,
|
|
339
|
+
model=self._orig_model,
|
|
340
|
+
dataset_name=dataset_name,
|
|
341
|
+
**util.get_fwd_compat_kwargs(),
|
|
342
|
+
)
|
|
343
|
+
|
|
322
344
|
def train_epoch(self):
|
|
323
345
|
"""
|
|
324
346
|
train one (sub)epoch
|
|
@@ -346,6 +368,8 @@ class Engine(EngineBase):
|
|
|
346
368
|
self._maybe_reset_dev_memory_caches()
|
|
347
369
|
self._reset_dev_memory_stats()
|
|
348
370
|
|
|
371
|
+
self._on_epoch_start(dataset_name="train")
|
|
372
|
+
|
|
349
373
|
if self.config.bool("debug_shell_before_train_loop", False):
|
|
350
374
|
print("debug_shell_before_train_loop", file=log.v1)
|
|
351
375
|
debug_shell(user_ns=locals(), user_global_ns=globals(), exit_afterwards=False)
|
|
@@ -564,6 +588,8 @@ class Engine(EngineBase):
|
|
|
564
588
|
|
|
565
589
|
self._maybe_report_dev_memory_stats()
|
|
566
590
|
|
|
591
|
+
self._on_epoch_end(dataset_name="train")
|
|
592
|
+
|
|
567
593
|
if self.epoch % self._save_model_epoch_interval == 0 or self.epoch == self._final_epoch:
|
|
568
594
|
if self.model_filename:
|
|
569
595
|
self._save_model()
|
|
@@ -612,6 +638,8 @@ class Engine(EngineBase):
|
|
|
612
638
|
|
|
613
639
|
print(f"Evaluating dataset {dataset_name!r}", file=log.v3)
|
|
614
640
|
|
|
641
|
+
self._on_epoch_start(dataset_name=dataset_name)
|
|
642
|
+
|
|
615
643
|
accumulated_losses_dict = NumbersDict()
|
|
616
644
|
accumulated_inv_norm_factors_dict = NumbersDict()
|
|
617
645
|
step_idx = 0
|
|
@@ -685,6 +713,8 @@ class Engine(EngineBase):
|
|
|
685
713
|
_has_data = torch.tensor([False], device="cpu", dtype=torch.int8)
|
|
686
714
|
torch.distributed.broadcast(_has_data, src=0)
|
|
687
715
|
|
|
716
|
+
self._on_epoch_end(dataset_name=dataset_name)
|
|
717
|
+
|
|
688
718
|
if not self._torch_distributed_ctx or self._torch_distributed_ctx.rank() == 0:
|
|
689
719
|
print(
|
|
690
720
|
f"Epoch {self.epoch} evaluation:",
|
returnn/util/basic.py
CHANGED
|
@@ -3153,42 +3153,53 @@ class LockFile:
|
|
|
3153
3153
|
Acquires the lock.
|
|
3154
3154
|
"""
|
|
3155
3155
|
import time
|
|
3156
|
-
import errno
|
|
3157
3156
|
|
|
3158
3157
|
wait_count = 0
|
|
3159
3158
|
while True:
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3159
|
+
if self.try_lock():
|
|
3160
|
+
break
|
|
3161
|
+
# We did not get the lock. Wait a bit, and then retry.
|
|
3162
|
+
time.sleep(min(wait_count * 0.1, 1.0))
|
|
3163
|
+
wait_count += 1
|
|
3164
|
+
if wait_count == 10:
|
|
3165
|
+
print("Waiting for lock-file: %s" % self.lockfile)
|
|
3166
|
+
|
|
3167
|
+
def try_lock(self) -> bool:
|
|
3168
|
+
"""
|
|
3169
|
+
Tries to acquire the lock.
|
|
3170
|
+
|
|
3171
|
+
:return: whether the lock was acquired
|
|
3172
|
+
"""
|
|
3173
|
+
|
|
3174
|
+
import errno
|
|
3175
|
+
|
|
3176
|
+
# Try to create directory if it does not exist.
|
|
3177
|
+
try:
|
|
3178
|
+
os.makedirs(self.directory)
|
|
3179
|
+
except OSError as exc:
|
|
3180
|
+
# Possible errors:
|
|
3181
|
+
# ENOENT (No such file or directory), e.g. if some parent directory was deleted.
|
|
3182
|
+
# EEXIST (File exists), if the dir already exists.
|
|
3183
|
+
if exc.errno not in [errno.ENOENT, errno.EEXIST]:
|
|
3184
|
+
# Other error, so reraise.
|
|
3185
|
+
# Common ones are e.g.:
|
|
3186
|
+
# ENOSPC (No space left on device)
|
|
3187
|
+
# EACCES (Permission denied)
|
|
3188
|
+
raise
|
|
3189
|
+
# Ignore those errors.
|
|
3190
|
+
|
|
3191
|
+
for _ in range(2):
|
|
3174
3192
|
# Now try to create the lock.
|
|
3175
3193
|
try:
|
|
3176
3194
|
self.fd = os.open(self.lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
|
|
3177
|
-
return
|
|
3195
|
+
return True
|
|
3178
3196
|
except OSError as exc:
|
|
3179
|
-
# Possible errors:
|
|
3180
|
-
# ENOENT (No such file or directory), e.g. if the directory was deleted.
|
|
3181
|
-
# EEXIST (File exists), if the lock already exists.
|
|
3182
3197
|
if exc.errno not in [errno.ENOENT, errno.EEXIST]:
|
|
3183
|
-
raise #
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
time.sleep(1)
|
|
3189
|
-
wait_count += 1
|
|
3190
|
-
if wait_count == 10:
|
|
3191
|
-
print("Waiting for lock-file: %s" % self.lockfile)
|
|
3198
|
+
raise # raise any other error
|
|
3199
|
+
# We did not get the lock.
|
|
3200
|
+
# Remove potential stale lockfile before retrying.
|
|
3201
|
+
self.maybe_remove_old_lockfile()
|
|
3202
|
+
return False
|
|
3192
3203
|
|
|
3193
3204
|
def unlock(self):
|
|
3194
3205
|
"""
|
returnn/util/file_cache.py
CHANGED
|
@@ -126,11 +126,8 @@ class FileCache:
|
|
|
126
126
|
raise e
|
|
127
127
|
if last_error is not None:
|
|
128
128
|
raise last_error
|
|
129
|
-
info_file = self._get_info_filename(dst_filename)
|
|
130
|
-
os.utime(dst_filename, None)
|
|
131
|
-
os.utime(info_file, None)
|
|
132
129
|
# protect info file from tempreaper, which looks at the mtime
|
|
133
|
-
self._touch_files_thread.files_extend([dst_filename,
|
|
130
|
+
self._touch_files_thread.files_extend([dst_filename, self._get_info_filename(dst_filename)])
|
|
134
131
|
return dst_filename
|
|
135
132
|
|
|
136
133
|
def release_files(self, filenames: Union[str, Iterable[str]]):
|
|
@@ -181,6 +178,9 @@ class FileCache:
|
|
|
181
178
|
elif self._is_info_filename(fn):
|
|
182
179
|
# skip keepalive files, they are processed together with the file they guard
|
|
183
180
|
continue
|
|
181
|
+
elif self._is_lock_filename(fn):
|
|
182
|
+
# skip lock files, removing them would accidentally release locks
|
|
183
|
+
continue
|
|
184
184
|
try:
|
|
185
185
|
f_stat = os.stat(fn)
|
|
186
186
|
except Exception as exc:
|
|
@@ -203,45 +203,85 @@ class FileCache:
|
|
|
203
203
|
for mtime, neg_size, fn in all_files:
|
|
204
204
|
size = -neg_size
|
|
205
205
|
delete_reason = None
|
|
206
|
-
if cur_time - mtime > self._cleanup_files_always_older_than_days * 60 * 60 * 24:
|
|
207
|
-
delete_reason = f"File is {(cur_time - mtime) / 60 / 60 / 24:.1f} days old"
|
|
208
|
-
else:
|
|
209
|
-
reached_more_recent_files = True
|
|
210
|
-
if not delete_reason and need_at_least_free_space_size > cur_expected_free:
|
|
211
|
-
# Still must delete some files.
|
|
212
|
-
if cur_time - mtime > cur_used_time_threshold:
|
|
213
|
-
delete_reason = f"Still need more space, file is {(cur_time - mtime) / 60 / 60:.1f} hours old"
|
|
214
|
-
else:
|
|
215
|
-
raise Exception(
|
|
216
|
-
f"We cannot free enough space on {self.cache_directory}.\n"
|
|
217
|
-
f"Needed: {human_bytes_size(need_at_least_free_space_size)},\n"
|
|
218
|
-
f"currently available: {human_bytes_size(cur_expected_free)},\n"
|
|
219
|
-
f"oldest file is still too recent: {fn}.\n"
|
|
220
|
-
f"{report_size_str}"
|
|
221
|
-
)
|
|
222
|
-
if not delete_reason and want_free_space_size > cur_expected_free:
|
|
223
|
-
if cur_time - mtime > self._cleanup_files_wanted_older_than_days * 60 * 60 * 24:
|
|
224
|
-
delete_reason = f"Still want more space, file is {(cur_time - mtime) / 60 / 60:.1f} hours old"
|
|
225
|
-
else:
|
|
226
|
-
# All further files are even more recent, so we would neither cleanup them,
|
|
227
|
-
# so we can also just stop now.
|
|
228
|
-
break
|
|
229
206
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
207
|
+
lock_dir, lock_file_name = self._get_lock_filename(fn)
|
|
208
|
+
lock_file = LockFile(directory=lock_dir, name=lock_file_name, lock_timeout=self._lock_timeout)
|
|
209
|
+
if not lock_file.try_lock():
|
|
210
|
+
print(f"FileCache: lock for {fn} is currently held, skipping.")
|
|
211
|
+
continue
|
|
212
|
+
try:
|
|
213
|
+
# Re-check mtime with lock, could have been updated by another
|
|
214
|
+
# process in the meantime.
|
|
215
|
+
# We do not update the `mtime` variable here, because the code
|
|
216
|
+
# assumes that the list of files is sorted by mtime to abort
|
|
217
|
+
# early when enough space has been made.
|
|
218
|
+
# Instead, we treat the case where the mtime was updated during
|
|
219
|
+
# cleanup as an outlier and continue as if no other mtimes had
|
|
220
|
+
# changed.
|
|
221
|
+
# See for discussion:
|
|
222
|
+
# - https://github.com/rwth-i6/returnn/issues/1675
|
|
223
|
+
# - https://github.com/rwth-i6/returnn/pull/1709
|
|
241
224
|
try:
|
|
242
|
-
os.
|
|
225
|
+
cur_mtime = os.stat(fn).st_mtime
|
|
226
|
+
except FileNotFoundError:
|
|
227
|
+
# File was deleted while waiting for the lock, or because it was
|
|
228
|
+
# a temporary copy file and was renamed to its final location.
|
|
229
|
+
# Since we don't know whether it was actually deleted or just
|
|
230
|
+
# renamed, we leave cur_expected_free unchanged.
|
|
231
|
+
continue
|
|
243
232
|
except Exception as exc:
|
|
244
|
-
print(f"FileCache:
|
|
233
|
+
print(f"FileCache: Error refreshing mtime of {fn}: {type(exc).__name__}: {exc}")
|
|
234
|
+
continue
|
|
235
|
+
if cur_mtime > mtime and (time.time() - cur_mtime) <= cur_used_time_threshold:
|
|
236
|
+
print(f"FileCache: {fn} has been updated during cleanup, skipping.")
|
|
237
|
+
continue
|
|
238
|
+
if cur_time - mtime > self._cleanup_files_always_older_than_days * 60 * 60 * 24:
|
|
239
|
+
delete_reason = f"File is {(cur_time - mtime) / 60 / 60 / 24:.1f} days old"
|
|
240
|
+
else:
|
|
241
|
+
reached_more_recent_files = True
|
|
242
|
+
if not delete_reason and need_at_least_free_space_size > cur_expected_free:
|
|
243
|
+
# Still must delete some files.
|
|
244
|
+
if cur_time - mtime > cur_used_time_threshold:
|
|
245
|
+
delete_reason = f"Still need more space, file is {(cur_time - mtime) / 60 / 60:.1f} hours old"
|
|
246
|
+
else:
|
|
247
|
+
raise Exception(
|
|
248
|
+
f"We cannot free enough space on {self.cache_directory}.\n"
|
|
249
|
+
f"Needed: {human_bytes_size(need_at_least_free_space_size)},\n"
|
|
250
|
+
f"currently available: {human_bytes_size(cur_expected_free)},\n"
|
|
251
|
+
f"oldest file is still too recent: {fn}.\n"
|
|
252
|
+
f"{report_size_str}"
|
|
253
|
+
)
|
|
254
|
+
if not delete_reason and want_free_space_size > cur_expected_free:
|
|
255
|
+
if cur_time - mtime > self._cleanup_files_wanted_older_than_days * 60 * 60 * 24:
|
|
256
|
+
delete_reason = f"Still want more space, file is {(cur_time - mtime) / 60 / 60:.1f} hours old"
|
|
257
|
+
else:
|
|
258
|
+
# All further files are even more recent, so we would neither cleanup them,
|
|
259
|
+
# so we can also just stop now.
|
|
260
|
+
break
|
|
261
|
+
|
|
262
|
+
if delete_reason:
|
|
263
|
+
cur_expected_free += size
|
|
264
|
+
print(
|
|
265
|
+
f"FileCache: Delete file {fn}, size {human_bytes_size(size)}. {delete_reason}."
|
|
266
|
+
f" After deletion, have {human_bytes_size(cur_expected_free)} free space."
|
|
267
|
+
)
|
|
268
|
+
try:
|
|
269
|
+
os.remove(fn)
|
|
270
|
+
except Exception as exc:
|
|
271
|
+
if not isinstance(exc, FileNotFoundError):
|
|
272
|
+
print(f"FileCache: Error while removing {fn}: {type(exc).__name__}: {exc}")
|
|
273
|
+
|
|
274
|
+
# We don't know whether the file was just renamed or actually deleted, so
|
|
275
|
+
# we do as if its space has not been freed.
|
|
276
|
+
cur_expected_free -= size
|
|
277
|
+
try:
|
|
278
|
+
os.remove(self._get_info_filename(fn))
|
|
279
|
+
except FileNotFoundError:
|
|
280
|
+
pass
|
|
281
|
+
except Exception as exc:
|
|
282
|
+
print(f"FileCache: Ignoring error file removing info file of {fn}: {type(exc).__name__}: {exc}")
|
|
283
|
+
finally:
|
|
284
|
+
lock_file.unlock()
|
|
245
285
|
|
|
246
286
|
if reached_more_recent_files and want_free_space_size <= cur_expected_free:
|
|
247
287
|
# Have enough free space now.
|
|
@@ -311,6 +351,16 @@ class FileCache:
|
|
|
311
351
|
""":return: the name of the corresponding info file to `filename`."""
|
|
312
352
|
return f"{filename}.returnn-info"
|
|
313
353
|
|
|
354
|
+
@staticmethod
|
|
355
|
+
def _get_lock_filename(filename: str) -> Tuple[str, str]:
|
|
356
|
+
""":return: lock file target directory and lock file name"""
|
|
357
|
+
return os.path.dirname(filename), os.path.basename(filename) + ".returnn-lock"
|
|
358
|
+
|
|
359
|
+
@staticmethod
|
|
360
|
+
def _is_lock_filename(filename: str) -> bool:
|
|
361
|
+
""":return: whether `filename` points to a lock file."""
|
|
362
|
+
return filename.endswith(".returnn-lock")
|
|
363
|
+
|
|
314
364
|
@staticmethod
|
|
315
365
|
def _is_info_filename(filename: str) -> bool:
|
|
316
366
|
""":return: whether `filename` points to a info file."""
|
|
@@ -324,13 +374,22 @@ class FileCache:
|
|
|
324
374
|
dst_dir = os.path.dirname(dst_filename)
|
|
325
375
|
os.makedirs(dst_dir, exist_ok=True)
|
|
326
376
|
|
|
377
|
+
lock_dir, lock_file = self._get_lock_filename(dst_filename)
|
|
378
|
+
info_file_name = self._get_info_filename(dst_filename)
|
|
379
|
+
|
|
327
380
|
# Copy the file, while holding a lock. See comment on lock_timeout above.
|
|
328
381
|
with LockFile(
|
|
329
|
-
directory=
|
|
382
|
+
directory=lock_dir, name=lock_file, lock_timeout=self._lock_timeout
|
|
330
383
|
) as lock, self._touch_files_thread.files_added_context(lock.lockfile):
|
|
331
384
|
# Maybe it was copied in the meantime, while waiting for the lock.
|
|
332
385
|
if self._check_existing_copied_file_maybe_cleanup(src_filename, dst_filename):
|
|
333
386
|
print(f"FileCache: using existing file {dst_filename}")
|
|
387
|
+
# Update mtime while holding lock, to synchronize with any concurrent cleanup.
|
|
388
|
+
# See for discussion:
|
|
389
|
+
# - https://github.com/rwth-i6/returnn/issues/1675
|
|
390
|
+
# - https://github.com/rwth-i6/returnn/pull/1709
|
|
391
|
+
os.utime(dst_filename, None)
|
|
392
|
+
os.utime(info_file_name, None)
|
|
334
393
|
return
|
|
335
394
|
|
|
336
395
|
print(f"FileCache: Copy file {src_filename} to cache")
|
|
@@ -352,7 +411,7 @@ class FileCache:
|
|
|
352
411
|
with self._touch_files_thread.files_added_context(dst_dir):
|
|
353
412
|
# save mtime before the copy process to have it pessimistic
|
|
354
413
|
orig_mtime_ns = os.stat(src_filename).st_mtime_ns
|
|
355
|
-
FileInfo(mtime_ns=orig_mtime_ns).save(
|
|
414
|
+
FileInfo(mtime_ns=orig_mtime_ns).save(info_file_name)
|
|
356
415
|
|
|
357
416
|
_copy_with_prealloc(src_filename, dst_tmp_filename)
|
|
358
417
|
os.rename(dst_tmp_filename, dst_filename)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
returnn/PKG-INFO,sha256=
|
|
1
|
+
returnn/PKG-INFO,sha256=7FZF3sif_hKT_9vHgl4snASut9Lc4uPAOGJfqaOxr_A,5215
|
|
2
2
|
returnn/__init__.py,sha256=biBtRsM0WZ406vShaeH-9WFoqJ8XwTbn6g0EeFJ7l8E,1012
|
|
3
3
|
returnn/__main__.py,sha256=qBFbuB1yN3adgVM5pXt2-Yq9vorjRNchNPL8kDKx44M,31752
|
|
4
4
|
returnn/__old_mod_loader__.py,sha256=nvsNY-xELdS_IPNkv66Q9Rmvg4dbGW0-EBRDcCmctos,7654
|
|
5
5
|
returnn/__setup__.py,sha256=22kQn2fh11iPM0hLb2Fy5sLmoU1JGvmDxXRYuRgQkwU,4659
|
|
6
|
-
returnn/_setup_info_generated.py,sha256=
|
|
6
|
+
returnn/_setup_info_generated.py,sha256=_2mdcTTEJ__VlmLagOoes0sVhrZN1SeK64wJQZ4crrY,77
|
|
7
7
|
returnn/config.py,sha256=3tmKhB6FnQZaNdtcYsiB61JnEY--iZ2qmJ4yq0b6tE0,29140
|
|
8
8
|
returnn/forward_iface.py,sha256=A_OJiaXsX4MlXQRzST86ylyxSUZbC402PQL1REcqHjM,911
|
|
9
9
|
returnn/learning_rate_control.py,sha256=ZvWryAn_tv9DhV8sh1LV3eE34Yltl3On3mYZAG4hR9s,34684
|
|
@@ -13,7 +13,7 @@ returnn/native_op.py,sha256=yqpE7SqBqXq77FCVnWMloUwadWlslEk-VzdK7FMpt_U,244411
|
|
|
13
13
|
returnn/pretrain.py,sha256=MHiXJZqkQFmDVyaYsGpd_Acv20wxl7Pr6s6qJzAT2FI,22648
|
|
14
14
|
returnn/datasets/__init__.py,sha256=PvDlfDOaaopIeUIt0OSvHD2eHZkdkyE-sjMXf35EH5U,390
|
|
15
15
|
returnn/datasets/audio.py,sha256=Gmj7a08dnvYh7Z-G1TNapz42L50AIcDE9JeIZaO1s1M,23334
|
|
16
|
-
returnn/datasets/basic.py,sha256=
|
|
16
|
+
returnn/datasets/basic.py,sha256=6rMpSuXFCZlqYtXlMW8xb5hu9ZCMlZDgnpmC66TYpQI,72367
|
|
17
17
|
returnn/datasets/bundle_file.py,sha256=KQNrS1MSf-4_idlK0c0KFwON-f5sEK0sWU15WpoMYpE,2380
|
|
18
18
|
returnn/datasets/cached.py,sha256=DIRdWrxBmsZG8O_9eVxBO5mcdo4f5KU-Xb-4wVz59Io,25418
|
|
19
19
|
returnn/datasets/cached2.py,sha256=_6pza3IG68JexaExhj1ld3fP6pE7T-G804driJ9Z_qo,12141
|
|
@@ -34,7 +34,7 @@ returnn/datasets/text_dict.py,sha256=BPE73nh6-vtSLy3SiDf4dpFl9RJorE7oO6l5y2FU3MI
|
|
|
34
34
|
returnn/datasets/util/__init__.py,sha256=rEKhSD6fyhDiQF-x7dUQMwa29JZu72SDm7mYcCcLghY,52
|
|
35
35
|
returnn/datasets/util/feature_extraction.py,sha256=axtXDb9wcNpOmyhmW3WJUj5xda29TKkKvOcGGvq7ExA,23923
|
|
36
36
|
returnn/datasets/util/strings.py,sha256=Xg-Nt2mI5Gi7Eb1bER1bmkZJdQg6QhnMANZOf1IzzJ4,413
|
|
37
|
-
returnn/datasets/util/vocabulary.py,sha256=
|
|
37
|
+
returnn/datasets/util/vocabulary.py,sha256=hkeuhCt4r6rD5YdICk3_lP0qL7NowK6Mn-oWRjpo3yo,26943
|
|
38
38
|
returnn/engine/__init__.py,sha256=br7hpn8i_hIBi2uTQfnN3BF9g5DREYa_mQi0_Nvlu6o,228
|
|
39
39
|
returnn/engine/base.py,sha256=0n4FtB_B2H3W_9KdoLr0P7YPER-hVkbk69pwFqsqmqw,18467
|
|
40
40
|
returnn/engine/batch.py,sha256=amXW8mGspuSQjo00JdisE2eOLy5Ij1weWWzkE-lXSJM,9912
|
|
@@ -207,7 +207,7 @@ returnn/tf/util/open_fst.py,sha256=sZRDw4TbxvhGqpGdUJWy1ebvlZm4_RPhygpRw9uLAOQ,1
|
|
|
207
207
|
returnn/torch/README.md,sha256=jzJ2FpOHW02vxN69yKaV97C9LI-hmvjBglKfdZXIDdc,85
|
|
208
208
|
returnn/torch/__init__.py,sha256=MHEUyNHB20Vy89uKAqZoj6FxJKF1Gq3HW-i6ra1pNcI,24
|
|
209
209
|
returnn/torch/distributed.py,sha256=skFyutdVztxgTEk3HHJ8S83qRWbNpkNT8Tj16Ic0_hE,6981
|
|
210
|
-
returnn/torch/engine.py,sha256=
|
|
210
|
+
returnn/torch/engine.py,sha256=yfqP9jzOH1OjiETqoBh20YOeEaX_kyr_kwPUkhSFxiI,77833
|
|
211
211
|
returnn/torch/updater.py,sha256=GqtBvZpElPVMm0lq84JPl4NVLFFETZAzAbR0rTomSao,28249
|
|
212
212
|
returnn/torch/data/__init__.py,sha256=6cLNEi8KoGI12PF6akN7mI_mtjlx-0hcQAfMYoExwik,132
|
|
213
213
|
returnn/torch/data/extern_data.py,sha256=OSoy3x1KiyiJCr7DfF5uPFAu09We2N2WbA0yo-pYXxM,7601
|
|
@@ -233,12 +233,12 @@ returnn/torch/util/gradient_checkpoint.py,sha256=iLy-FB65DC8O6LxzmMvFjnSdpIVpko8
|
|
|
233
233
|
returnn/torch/util/module.py,sha256=MXHIrF9Isu575DDJIa81212ULKwdqu1oOLxDVZecVSk,1693
|
|
234
234
|
returnn/torch/util/scaled_gradient.py,sha256=3585VuNypBty-pW6r3BKK047H3MqZQSdMjXeYAb4cmU,3192
|
|
235
235
|
returnn/util/__init__.py,sha256=UIG1qw4idqhW71BV60ha7h9PktxvEVcBIu0lYRossK8,336
|
|
236
|
-
returnn/util/basic.py,sha256=
|
|
236
|
+
returnn/util/basic.py,sha256=jwtaaZyOV7fUjKDRXVHDy-K5kwR1mPrkAZrzc5STOvE,142554
|
|
237
237
|
returnn/util/better_exchook.py,sha256=TAtb_ZyM-357UnOg_HMoBZUSxzt0WPgumlvprmlCprA,63921
|
|
238
238
|
returnn/util/bpe.py,sha256=LWFhICZsEOnMwNws0lybPNzKRX6rSr8yKCvP65vjl9Y,19656
|
|
239
239
|
returnn/util/debug.py,sha256=wuRzdg9zB84WWCGyTjmRR_zYypu8gXxlc0nZ6si9OC8,28224
|
|
240
240
|
returnn/util/debug_helpers.py,sha256=0EINLK4uLtoSt5_kHs1M2NIFpMd0S7i4c4rx90U4fJk,2914
|
|
241
|
-
returnn/util/file_cache.py,sha256=
|
|
241
|
+
returnn/util/file_cache.py,sha256=tXM2Leos8fOc1tzmQbGSLYgzQoKAw1klCw-k9TwoAno,26453
|
|
242
242
|
returnn/util/fsa.py,sha256=k2lJ8tyf_g44Xk1EPVLwDwpP4spoMTqIigDVOWocQHY,59177
|
|
243
243
|
returnn/util/literal_py_to_pickle.py,sha256=3dnjWPeeiDT2xp4bRDgIf9yddx7b1AG7mOKEn_jiSl8,2173
|
|
244
244
|
returnn/util/lru_cache.py,sha256=7Q5H3a8b07E8e1iB7PA9jCpRnxMJZOFS2KO07cy0gqk,11446
|
|
@@ -253,8 +253,8 @@ returnn/util/sig_proc.py,sha256=Tjz0VOAVyqu2qDCF5HZ1JjALjcFsHcNkcd96WgZeKfE,7265
|
|
|
253
253
|
returnn/util/task_system.py,sha256=y4sMVXQ25Qd2z0rx03uOlXlkE-jbCYC1Sjfn-XlraVU,26003
|
|
254
254
|
returnn/util/train_proc_manager.py,sha256=Pjht28k6uz6BNQ47uW6Gf880iyq5q4wx7P_K2tmoAM8,3266
|
|
255
255
|
returnn/util/watch_memory.py,sha256=BR5P2kvBN6UI81cE0_1WAA6Hd1SByLbBaiDxvLhPOew,4213
|
|
256
|
-
returnn-1.
|
|
257
|
-
returnn-1.
|
|
258
|
-
returnn-1.
|
|
259
|
-
returnn-1.
|
|
260
|
-
returnn-1.
|
|
256
|
+
returnn-1.20250423.105638.dist-info/LICENSE,sha256=ywBD_U2aD4vpuoIgNAsjIGBYydl0tVKll3De0Z8s77c,11041
|
|
257
|
+
returnn-1.20250423.105638.dist-info/METADATA,sha256=7FZF3sif_hKT_9vHgl4snASut9Lc4uPAOGJfqaOxr_A,5215
|
|
258
|
+
returnn-1.20250423.105638.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
259
|
+
returnn-1.20250423.105638.dist-info/top_level.txt,sha256=Lsn4WZc5Pbfk0-xDQOgnFCxOoqxL4CyeM3N1TFbJncw,8
|
|
260
|
+
returnn-1.20250423.105638.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|