code-loader 1.0.204.dev1__tar.gz → 1.0.204.dev5__tar.gz
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.
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/PKG-INFO +1 -1
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/datasetclasses.py +1 -1
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/inner_leap_binder/leapbinder.py +12 -1
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/inner_leap_binder/leapbinder_decorators.py +57 -5
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/utils.py +75 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/pyproject.toml +1 -1
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/LICENSE +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/README.md +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/__init__.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/__init__.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/enums.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/exceptions.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/mapping.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/responsedataclasses.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/sim_config.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/visualizer_classes.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/default_losses.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/default_metrics.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/__init__.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/api.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/cli_config_utils.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/client.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/epoch.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/experiment.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/experiment_context.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/types.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/utils.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/inner_leap_binder/__init__.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/leaploader.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/leaploaderbase.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/mixpanel_tracker.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/plot_functions/__init__.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/plot_functions/plot_functions.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/plot_functions/visualize.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/visualizers/__init__.py +0 -0
- {code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/visualizers/default_visualizers.py +0 -0
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/datasetclasses.py
RENAMED
|
@@ -309,7 +309,7 @@ class MetadataHandler:
|
|
|
309
309
|
|
|
310
310
|
@dataclass
|
|
311
311
|
class CustomLatentSpaceHandler:
|
|
312
|
-
function: SectionCallableInterface
|
|
312
|
+
function: Union[SectionCallableInterface, InstanceSectionCallableInterface]
|
|
313
313
|
name: str = 'custom_latent_space'
|
|
314
314
|
use_ls_for_analysis: bool = False
|
|
315
315
|
instance_aware: bool = False
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/inner_leap_binder/leapbinder.py
RENAMED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import builtins
|
|
3
3
|
import inspect
|
|
4
4
|
import os
|
|
5
|
+
import warnings
|
|
5
6
|
from contextlib import contextmanager
|
|
6
7
|
from typing import Callable, List, Optional, Dict, Any, Type, Union, get_args, cast, Iterator, Set
|
|
7
8
|
|
|
@@ -565,7 +566,8 @@ class LeapBinder:
|
|
|
565
566
|
use_ls_for_analysis (bool): When True, the engine uses this custom latent
|
|
566
567
|
space for the Out-Of-Distribution and Domain-Gap insights instead of the
|
|
567
568
|
built-in defaults. At most one registered custom latent space may set this;
|
|
568
|
-
registering a second one with the flag raises.
|
|
569
|
+
registering a second one with the flag raises. Not currently supported when
|
|
570
|
+
instance_aware=True — it is ignored (with a warning) and forced to False.
|
|
569
571
|
instance_aware (bool): When True, `function` takes a third `instance_id` argument
|
|
570
572
|
and is called once per element-instance row instead of once per sample.
|
|
571
573
|
"""
|
|
@@ -577,6 +579,15 @@ class LeapBinder:
|
|
|
577
579
|
f"@tensorleap_custom_latent_space must have a unique name "
|
|
578
580
|
f"(pass name='...' to distinguish them)."
|
|
579
581
|
)
|
|
582
|
+
# use_ls_for_analysis is not currently wired for instance-aware latent spaces (OOD /
|
|
583
|
+
# Domain-Gap analyze the sample-level population, not instance rows) — force it off rather
|
|
584
|
+
# than silently accepting a flag that has no effect.
|
|
585
|
+
if instance_aware and use_ls_for_analysis:
|
|
586
|
+
warnings.warn(
|
|
587
|
+
f"use_ls_for_analysis=True is not currently supported for an instance-aware custom "
|
|
588
|
+
f"latent space ('{name}'). Ignoring it; the flag will be set to False."
|
|
589
|
+
)
|
|
590
|
+
use_ls_for_analysis = False
|
|
580
591
|
if use_ls_for_analysis:
|
|
581
592
|
already_flagged = [
|
|
582
593
|
existing_name
|
|
@@ -16,7 +16,9 @@ import numpy as np
|
|
|
16
16
|
import numpy.typing as npt
|
|
17
17
|
|
|
18
18
|
from code_loader.utils import get_metadata_type_from_variable, map_dict_to_metadata_types, \
|
|
19
|
-
validate_autoregressive_state_types, autoregressive_nests_equal
|
|
19
|
+
validate_autoregressive_state_types, autoregressive_nests_equal, \
|
|
20
|
+
simulate_engine_float16_downcast_on_call_args, ENGINE_STORAGE_DTYPE, \
|
|
21
|
+
TL_DISABLE_ENGINE_FLOAT16_SIMULATION_ENV_VAR
|
|
20
22
|
|
|
21
23
|
logger = logging.getLogger(__name__)
|
|
22
24
|
|
|
@@ -308,6 +310,35 @@ def _require_sample_preprocess_response_supplied(user_function: Callable, args:
|
|
|
308
310
|
f"SamplePreprocessResponse(sample_id, preprocess)).")
|
|
309
311
|
|
|
310
312
|
|
|
313
|
+
def _simulate_engine_tensor_dtype(args: tuple, kwargs: dict):
|
|
314
|
+
"""Hand a metric / loss the tensor dtype the platform will hand it.
|
|
315
|
+
|
|
316
|
+
The engine downcasts every tensor to float16 before pushing it to Redis, and metrics and
|
|
317
|
+
losses read their tensors back from there. A local run would otherwise pass the float32
|
|
318
|
+
arrays straight from the encoders and the model, so a float32-only loss (a Keras/TF loss
|
|
319
|
+
that refuses a float16 y_pred, say) passes the local test and only fails in evaluation.
|
|
320
|
+
Downcasting here makes the local test fail the same way, before the project is pushed.
|
|
321
|
+
|
|
322
|
+
No-op on the platform, where the tensors already arrive downcast. Returns the (possibly
|
|
323
|
+
rewritten) call args plus whether anything was actually downcast.
|
|
324
|
+
"""
|
|
325
|
+
if _call_from_tl_platform:
|
|
326
|
+
return args, kwargs, False
|
|
327
|
+
downcast_args, downcast_kwargs = simulate_engine_float16_downcast_on_call_args(args, kwargs)
|
|
328
|
+
was_downcast = any(arg is not original for arg, original in zip(downcast_args, args)) or \
|
|
329
|
+
any(arg is not kwargs[arg_name] for arg_name, arg in downcast_kwargs.items())
|
|
330
|
+
return downcast_args, downcast_kwargs, was_downcast
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def _print_engine_float16_simulation_hint(func_name: str) -> None:
|
|
334
|
+
print(f"note: {func_name}() received its tensors as {np.dtype(ENGINE_STORAGE_DTYPE).name} — "
|
|
335
|
+
f"the platform stores every tensor at that precision, so the local test feeds the same "
|
|
336
|
+
f"dtype the engine will. If the failure above is a dtype mismatch, cast inside "
|
|
337
|
+
f"{func_name}() (e.g. arr.astype(np.float32)) rather than relying on the caller's "
|
|
338
|
+
f"dtype. Set {TL_DISABLE_ENGINE_FLOAT16_SIMULATION_ENV_VAR}=true to opt out of this "
|
|
339
|
+
f"simulation locally.")
|
|
340
|
+
|
|
341
|
+
|
|
311
342
|
def _warn_loss_inputs_not_wired_to_model() -> None:
|
|
312
343
|
"""Warn when a custom loss consumes an input encoder the model is not given.
|
|
313
344
|
|
|
@@ -900,7 +931,10 @@ def tensorleap_custom_metric(name: str,
|
|
|
900
931
|
)
|
|
901
932
|
|
|
902
933
|
else:
|
|
903
|
-
|
|
934
|
+
# np.floating, not just np.float32: metric inputs are downcast to the
|
|
935
|
+
# engine's float16, so a metric that returns its computed values as numpy
|
|
936
|
+
# scalars now yields np.float16 ones.
|
|
937
|
+
assert all(isinstance(v, (float, int, type(None), np.floating)) for v in single_metric_result), (
|
|
904
938
|
f"{supported_types_message}\n"
|
|
905
939
|
f"Got {'a dict where the value of ' + str(key) + ' is of type ' if key is not None else ''}"
|
|
906
940
|
f"List[{', '.join(type(v).__name__ for v in single_metric_result)}]."
|
|
@@ -1019,9 +1053,15 @@ def tensorleap_custom_metric(name: str,
|
|
|
1019
1053
|
def inner(*args, **kwargs):
|
|
1020
1054
|
if not _call_from_tl_platform:
|
|
1021
1055
|
set_current('tensorleap_custom_metric')
|
|
1056
|
+
args, kwargs, was_downcast = _simulate_engine_tensor_dtype(args, kwargs)
|
|
1022
1057
|
_validate_input_args(*args, **kwargs)
|
|
1023
1058
|
|
|
1024
|
-
|
|
1059
|
+
try:
|
|
1060
|
+
result = inner_without_validate(*args, **kwargs)
|
|
1061
|
+
except Exception:
|
|
1062
|
+
if was_downcast:
|
|
1063
|
+
_print_engine_float16_simulation_hint(user_function.__name__)
|
|
1064
|
+
raise
|
|
1025
1065
|
|
|
1026
1066
|
_validate_result(result)
|
|
1027
1067
|
if not _call_from_tl_platform:
|
|
@@ -1229,9 +1269,15 @@ def tensorleap_custom_instances_metric(name: str,
|
|
|
1229
1269
|
def inner(*args, **kwargs):
|
|
1230
1270
|
if not _call_from_tl_platform:
|
|
1231
1271
|
set_current('tensorleap_custom_instances_metric')
|
|
1272
|
+
args, kwargs, was_downcast = _simulate_engine_tensor_dtype(args, kwargs)
|
|
1232
1273
|
_validate_input_args(*args, **kwargs)
|
|
1233
1274
|
|
|
1234
|
-
|
|
1275
|
+
try:
|
|
1276
|
+
result = inner_without_validate(*args, **kwargs)
|
|
1277
|
+
except Exception:
|
|
1278
|
+
if was_downcast:
|
|
1279
|
+
_print_engine_float16_simulation_hint(user_function.__name__)
|
|
1280
|
+
raise
|
|
1235
1281
|
|
|
1236
1282
|
_validate_result(result)
|
|
1237
1283
|
if not _call_from_tl_platform:
|
|
@@ -3454,9 +3500,15 @@ def tensorleap_custom_loss(name: str, connects_to=None):
|
|
|
3454
3500
|
def inner(*args, **kwargs):
|
|
3455
3501
|
if not _call_from_tl_platform:
|
|
3456
3502
|
set_current("tensorleap_custom_loss")
|
|
3503
|
+
args, kwargs, was_downcast = _simulate_engine_tensor_dtype(args, kwargs)
|
|
3457
3504
|
_validate_input_args(*args, **kwargs)
|
|
3458
3505
|
|
|
3459
|
-
|
|
3506
|
+
try:
|
|
3507
|
+
result = inner_without_validate(*args, **kwargs)
|
|
3508
|
+
except Exception:
|
|
3509
|
+
if was_downcast:
|
|
3510
|
+
_print_engine_float16_simulation_hint(user_function.__name__)
|
|
3511
|
+
raise
|
|
3460
3512
|
|
|
3461
3513
|
_validate_result(result)
|
|
3462
3514
|
if not _call_from_tl_platform:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import math
|
|
3
|
+
import os
|
|
3
4
|
import pickle
|
|
4
5
|
import sys
|
|
5
6
|
from pathlib import Path
|
|
@@ -42,6 +43,80 @@ def to_numpy_return_masks_wrapper(encoder_function: InstanceCallableInterface) -
|
|
|
42
43
|
return numpy_encoder_function
|
|
43
44
|
|
|
44
45
|
|
|
46
|
+
# The engine downcasts every tensor to float16 before pushing it to Redis, and metrics and losses
|
|
47
|
+
# read their tensors back from there — so on the platform they are handed float16 arrays. A local
|
|
48
|
+
# run feeds them the float32 arrays straight from the encoders and the model, which is why a
|
|
49
|
+
# float32-only loss (e.g. a Keras/TF loss that refuses a float16 y_pred) passes the local test and
|
|
50
|
+
# then fails in evaluation. Mirror the engine locally so the failure surfaces before the push.
|
|
51
|
+
ENGINE_STORAGE_DTYPE = np.float16
|
|
52
|
+
# The engine's cast is range-guarded (redis_metrics_queue_manager.py): only a non-empty float32 /
|
|
53
|
+
# float64 array whose abs-max fits float16's finite range is cast, so an array holding large values
|
|
54
|
+
# (big logits, say) keeps its original dtype instead of overflowing to inf. Arrays holding NaN are
|
|
55
|
+
# left alone too — their abs-max is NaN, and `NaN <= max` is False.
|
|
56
|
+
ENGINE_STORAGE_DTYPE_MAX = 65504.0 # float16 finite max
|
|
57
|
+
ENGINE_DOWNCAST_SOURCE_DTYPES = (np.float32, np.float64)
|
|
58
|
+
TL_DISABLE_ENGINE_FLOAT16_SIMULATION_ENV_VAR = 'TL_DISABLE_ENGINE_FLOAT16_SIMULATION'
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def is_engine_float16_simulation_disabled() -> bool:
|
|
62
|
+
return os.environ.get(TL_DISABLE_ENGINE_FLOAT16_SIMULATION_ENV_VAR, '').lower() in \
|
|
63
|
+
('1', 'true', 'yes')
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def simulate_engine_float16_downcast(value: Any) -> Any:
|
|
67
|
+
"""Return ``value`` with its float tensors downcast the way the engine downcasts them.
|
|
68
|
+
|
|
69
|
+
Recurses into the containers a handler argument can arrive in (a grouped input is a list of
|
|
70
|
+
arrays). Only the arrays the engine would actually cast are touched — see
|
|
71
|
+
:func:`_downcast_array_to_engine_dtype`. Ints, bools and strings survive the engine's storage
|
|
72
|
+
unchanged, and anything that is not a tensor or a container of tensors
|
|
73
|
+
(SamplePreprocessResponse, for instance) is returned as is.
|
|
74
|
+
"""
|
|
75
|
+
if is_engine_float16_simulation_disabled():
|
|
76
|
+
return value
|
|
77
|
+
return _downcast_to_engine_dtype(value)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _downcast_array_to_engine_dtype(array: npt.NDArray[Any]) -> npt.NDArray[Any]:
|
|
81
|
+
"""Mirror the engine's guarded cast for a single array.
|
|
82
|
+
|
|
83
|
+
The engine casts an array to float16 only when it is a non-empty float32 / float64 array whose
|
|
84
|
+
whole-array abs-max fits float16's finite range; anything else is stored at its original dtype.
|
|
85
|
+
Casting unconditionally would diverge the other way — a local run would hand a handler ``inf``
|
|
86
|
+
where the platform hands it a finite float32.
|
|
87
|
+
"""
|
|
88
|
+
if array.dtype not in ENGINE_DOWNCAST_SOURCE_DTYPES or not array.size:
|
|
89
|
+
return array
|
|
90
|
+
# NaN fails this comparison, which is how the engine ends up leaving NaN-bearing arrays alone.
|
|
91
|
+
if not float(np.abs(array).max()) <= ENGINE_STORAGE_DTYPE_MAX:
|
|
92
|
+
return array
|
|
93
|
+
return array.astype(ENGINE_STORAGE_DTYPE)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _downcast_to_engine_dtype(value: Any) -> Any:
|
|
97
|
+
# Containers return the original object when no leaf changed, so callers can tell whether a
|
|
98
|
+
# downcast actually happened by identity.
|
|
99
|
+
if isinstance(value, np.ndarray):
|
|
100
|
+
return _downcast_array_to_engine_dtype(value)
|
|
101
|
+
if isinstance(value, (list, tuple)):
|
|
102
|
+
downcast = [_downcast_to_engine_dtype(item) for item in value]
|
|
103
|
+
if all(item is original for item, original in zip(downcast, value)):
|
|
104
|
+
return value
|
|
105
|
+
return downcast if isinstance(value, list) else tuple(downcast)
|
|
106
|
+
if isinstance(value, dict):
|
|
107
|
+
downcast_dict = {key: _downcast_to_engine_dtype(item) for key, item in value.items()}
|
|
108
|
+
if all(item is value[key] for key, item in downcast_dict.items()):
|
|
109
|
+
return value
|
|
110
|
+
return downcast_dict
|
|
111
|
+
return value
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def simulate_engine_float16_downcast_on_call_args(
|
|
115
|
+
args: Tuple[Any, ...], kwargs: Dict[str, Any]) -> Tuple[Tuple[Any, ...], Dict[str, Any]]:
|
|
116
|
+
return (tuple(simulate_engine_float16_downcast(arg) for arg in args),
|
|
117
|
+
{arg_name: simulate_engine_float16_downcast(arg) for arg_name, arg in kwargs.items()})
|
|
118
|
+
|
|
119
|
+
|
|
45
120
|
def get_root_traceback(exc_tb: TracebackType) -> TracebackType:
|
|
46
121
|
return_traceback = exc_tb
|
|
47
122
|
while return_traceback.tb_next is not None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/responsedataclasses.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/contract/visualizer_classes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/cli_config_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/experiment_api/experiment.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/inner_leap_binder/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/plot_functions/__init__.py
RENAMED
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/plot_functions/plot_functions.py
RENAMED
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/plot_functions/visualize.py
RENAMED
|
File without changes
|
|
File without changes
|
{code_loader-1.0.204.dev1 → code_loader-1.0.204.dev5}/code_loader/visualizers/default_visualizers.py
RENAMED
|
File without changes
|