mostlyai-engine 1.5.1__tar.gz → 1.5.3__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.
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/PKG-INFO +1 -1
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/__init__.py +1 -1
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_common.py +7 -10
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/common.py +3 -3
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_tabular/argn.py +22 -10
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/analysis.py +26 -7
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/pyproject.toml +1 -1
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/.gitignore +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/LICENSE +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/README.md +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_dtypes.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/__init__.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/__init__.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/categorical.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/datetime.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/numeric.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/text.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/__init__.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/categorical.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/character.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/datetime.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/itt.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/lat_long.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/numeric.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/__init__.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/encoding.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/engine/__init__.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/engine/base.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/engine/hf_engine.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/engine/vllm_engine.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/generation.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/lstm.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/tokenizer_utils.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/training.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/xgrammar_utils.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_memory.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_tabular/__init__.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_tabular/common.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_tabular/encoding.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_tabular/fairness.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_tabular/generation.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_tabular/training.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_training_utils.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_workspace.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/domain.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/encoding.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/generation.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/logging.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/random_state.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/splitting.py +0 -0
- {mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/training.py +0 -0
|
@@ -22,7 +22,7 @@ from mostlyai.engine.splitting import split
|
|
|
22
22
|
from mostlyai.engine.training import train
|
|
23
23
|
|
|
24
24
|
__all__ = ["split", "analyze", "encode", "train", "generate", "init_logging", "set_random_state"]
|
|
25
|
-
__version__ = "1.5.
|
|
25
|
+
__version__ = "1.5.3"
|
|
26
26
|
|
|
27
27
|
# suppress specific warning related to os.fork() in multi-threaded processes
|
|
28
28
|
warnings.filterwarnings("ignore", category=DeprecationWarning, message=".*multi-threaded.*fork.*")
|
|
@@ -401,12 +401,11 @@ def get_sub_columns_lookup(
|
|
|
401
401
|
return sub_cols_lookup
|
|
402
402
|
|
|
403
403
|
|
|
404
|
-
class CtxSequenceLengthError(Exception):
|
|
405
|
-
"""Error raised when the cols of the same table do not have the same stats value"""
|
|
406
|
-
|
|
407
|
-
|
|
408
404
|
def get_ctx_sequence_length(ctx_stats: dict, key: str) -> dict[str, int]:
|
|
409
|
-
|
|
405
|
+
"""
|
|
406
|
+
Get the stats of sequence lengths from the first column_stats of each context table
|
|
407
|
+
"""
|
|
408
|
+
ctxseq_stats: dict[str, int] = {}
|
|
410
409
|
|
|
411
410
|
for column_stats in ctx_stats.get("columns", {}).values():
|
|
412
411
|
if "seq_len" in column_stats:
|
|
@@ -414,12 +413,10 @@ def get_ctx_sequence_length(ctx_stats: dict, key: str) -> dict[str, int]:
|
|
|
414
413
|
argn_processor=column_stats[ARGN_PROCESSOR],
|
|
415
414
|
argn_table=column_stats[ARGN_TABLE],
|
|
416
415
|
)
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
raise CtxSequenceLengthError()
|
|
420
|
-
seq_stats[table] = column_stats["seq_len"][key]
|
|
416
|
+
if table not in ctxseq_stats:
|
|
417
|
+
ctxseq_stats[table] = column_stats["seq_len"][key]
|
|
421
418
|
|
|
422
|
-
return
|
|
419
|
+
return ctxseq_stats
|
|
423
420
|
|
|
424
421
|
|
|
425
422
|
def get_max_data_points_per_sample(stats: dict) -> int:
|
|
@@ -97,10 +97,10 @@ def load_base_model_and_config(
|
|
|
97
97
|
else:
|
|
98
98
|
quantization_config = None
|
|
99
99
|
|
|
100
|
-
if device.type == "cuda" and device.index is
|
|
101
|
-
device_map = str(device)
|
|
102
|
-
else:
|
|
100
|
+
if device.type == "cuda" and device.index is None:
|
|
103
101
|
device_map = "auto"
|
|
102
|
+
else: # device is `cpu` or `cuda:0` (when using single GPU on a multi-GPU instance)
|
|
103
|
+
device_map = str(device)
|
|
104
104
|
|
|
105
105
|
if hasattr(config, "text_config") and hasattr(config, "vision_config"):
|
|
106
106
|
config.text_config.use_cache = use_cache
|
|
@@ -216,8 +216,15 @@ class Embedders(nn.Module):
|
|
|
216
216
|
self.embedders = nn.ModuleDict()
|
|
217
217
|
|
|
218
218
|
# embedding layers for each sub column defined in cardinalities
|
|
219
|
+
has_ridx = any(sub_col.startswith(RIDX_SUB_COLUMN_PREFIX) for sub_col in self.cardinalities)
|
|
219
220
|
last_slen_sub_col = next(
|
|
220
|
-
(
|
|
221
|
+
(
|
|
222
|
+
sub_col
|
|
223
|
+
for sub_col in reversed(self.cardinalities)
|
|
224
|
+
if sub_col.startswith(SLEN_SUB_COLUMN_PREFIX)
|
|
225
|
+
if has_ridx # last SLEN sub column is dangling for model with RIDX only
|
|
226
|
+
),
|
|
227
|
+
None,
|
|
221
228
|
)
|
|
222
229
|
last_ridx_sub_col = next(
|
|
223
230
|
(sub_col for sub_col in reversed(self.cardinalities) if sub_col.startswith(RIDX_SUB_COLUMN_PREFIX)), None
|
|
@@ -1249,21 +1256,26 @@ class SequentialModel(nn.Module):
|
|
|
1249
1256
|
if context is None:
|
|
1250
1257
|
context = self.context_compressor(x)
|
|
1251
1258
|
|
|
1259
|
+
# SLEN is only masked for models with RIDX
|
|
1260
|
+
has_ridx = any(sub_col.startswith(RIDX_SUB_COLUMN_PREFIX) for sub_col in self.tgt_cardinalities)
|
|
1261
|
+
masked_positional_columns = (
|
|
1262
|
+
(SLEN_SUB_COLUMN_PREFIX, RIDX_SUB_COLUMN_PREFIX) if has_ridx else (RIDX_SUB_COLUMN_PREFIX,)
|
|
1263
|
+
)
|
|
1264
|
+
|
|
1252
1265
|
outputs = {}
|
|
1253
1266
|
if mode == "trn":
|
|
1254
1267
|
# forward pass through sub column embedders
|
|
1255
1268
|
tgt_embeds = self.embedders(x)
|
|
1256
|
-
|
|
1257
|
-
k: torch.zeros_like(v) if k.startswith(
|
|
1258
|
-
for k, v in tgt_embeds.items()
|
|
1269
|
+
tgt_embeds_positional_masked = {
|
|
1270
|
+
k: torch.zeros_like(v) if k.startswith(masked_positional_columns) else v for k, v in tgt_embeds.items()
|
|
1259
1271
|
}
|
|
1260
1272
|
|
|
1261
1273
|
# forward pass through column embedders
|
|
1262
|
-
tgt_col_embeds = self.column_embedders(
|
|
1274
|
+
tgt_col_embeds = self.column_embedders(tgt_embeds_positional_masked)
|
|
1263
1275
|
|
|
1264
1276
|
# history
|
|
1265
1277
|
# time shift: remove last time step; add zeros for first time step; add randoms for all others
|
|
1266
|
-
embeddings = torch.cat(list(
|
|
1278
|
+
embeddings = torch.cat(list(tgt_embeds_positional_masked.values()), dim=-1)
|
|
1267
1279
|
history_in = embeddings[:, :-1, :]
|
|
1268
1280
|
history_in = nn.ConstantPad2d((0, 0, 1, 0), 0)(history_in)
|
|
1269
1281
|
history, _ = self.history_compressor(history_in)
|
|
@@ -1393,20 +1405,20 @@ class SequentialModel(nn.Module):
|
|
|
1393
1405
|
|
|
1394
1406
|
# update current sub column embedding
|
|
1395
1407
|
tgt_embeds[sub_col] = self.embedders.get(sub_col)(out)
|
|
1396
|
-
|
|
1397
|
-
k: torch.zeros_like(v) if k.startswith(
|
|
1408
|
+
tgt_embeds_positional_masked = {
|
|
1409
|
+
k: torch.zeros_like(v) if k.startswith(masked_positional_columns) else v
|
|
1398
1410
|
for k, v in tgt_embeds.items()
|
|
1399
1411
|
}
|
|
1400
1412
|
|
|
1401
1413
|
# update current column embedding
|
|
1402
1414
|
if sub_col in self.tgt_last_sub_cols:
|
|
1403
1415
|
col_sub_cols = self.tgt_column_sub_columns[lookup.col_name]
|
|
1404
|
-
col_embed_in = torch.cat([
|
|
1416
|
+
col_embed_in = torch.cat([tgt_embeds_positional_masked[sc] for sc in col_sub_cols], dim=-1)
|
|
1405
1417
|
tgt_col_embeds[lookup.col_name] = self.column_embedders.get(lookup.col_name)(col_embed_in)
|
|
1406
1418
|
col_embeddings = torch.cat(list(tgt_col_embeds.values()), dim=-1)
|
|
1407
1419
|
|
|
1408
1420
|
# update history and hidden state
|
|
1409
|
-
history_in = torch.cat([v for v in
|
|
1421
|
+
history_in = torch.cat([v for v in tgt_embeds_positional_masked.values()], dim=-1)
|
|
1410
1422
|
history, history_state = self.history_compressor(history_in, history_state=history_state)
|
|
1411
1423
|
|
|
1412
1424
|
# order outputs according to tgt_sub_columns
|
|
@@ -339,13 +339,25 @@ def _analyze_reduce(
|
|
|
339
339
|
stats_list = [read_json(file) for file in stats_files]
|
|
340
340
|
stats: dict[str, Any] = {"columns": {}}
|
|
341
341
|
|
|
342
|
+
# check how many context tables have sequential context
|
|
343
|
+
if mode == "ctx":
|
|
344
|
+
ctxseq_stats = {}
|
|
345
|
+
ctxseq_tables = []
|
|
346
|
+
for column, column_stats in stats_list[0]["columns"].items():
|
|
347
|
+
if "seq_len" in column_stats:
|
|
348
|
+
table_name = column.split(TABLE_COLUMN_INFIX)[0]
|
|
349
|
+
if table_name not in ctxseq_tables:
|
|
350
|
+
ctxseq_tables.append(table_name)
|
|
351
|
+
n_ctxseq_tables = len(ctxseq_tables)
|
|
352
|
+
_LOG.info(f"{n_ctxseq_tables = }")
|
|
353
|
+
|
|
342
354
|
encoding_types = {
|
|
343
355
|
column: column_stats.get("encoding_type") for column, column_stats in stats_list[0]["columns"].items()
|
|
344
356
|
}
|
|
345
357
|
|
|
346
|
-
# ctx: distribute the privacy budget across all columns
|
|
358
|
+
# ctx: distribute the privacy budget across all columns + sequence lengths of n_ctxseq_tables
|
|
347
359
|
# tgt: distribute the privacy budget across all columns + sequence length
|
|
348
|
-
n_dp_splits = len(encoding_types) if mode == "ctx" else len(encoding_types) + 1
|
|
360
|
+
n_dp_splits = len(encoding_types) + n_ctxseq_tables if mode == "ctx" else len(encoding_types) + 1
|
|
349
361
|
_LOG.info(f"{value_protection = }")
|
|
350
362
|
if value_protection_epsilon is not None and n_dp_splits > 0:
|
|
351
363
|
_LOG.info(f"epsilon for analyzing each column and sequence length: {value_protection_epsilon / n_dp_splits}")
|
|
@@ -364,13 +376,13 @@ def _analyze_reduce(
|
|
|
364
376
|
stats["columns"][column] = {"encoding_type": encoding_type}
|
|
365
377
|
continue
|
|
366
378
|
|
|
367
|
-
|
|
368
|
-
"stats_list": column_stats_list,
|
|
379
|
+
value_protection_args = {
|
|
369
380
|
"value_protection": value_protection,
|
|
370
381
|
"value_protection_epsilon": value_protection_epsilon / n_dp_splits
|
|
371
382
|
if value_protection_epsilon is not None
|
|
372
383
|
else None,
|
|
373
384
|
}
|
|
385
|
+
analyze_reduce_column_args = {"stats_list": column_stats_list} | value_protection_args
|
|
374
386
|
|
|
375
387
|
match encoding_type:
|
|
376
388
|
case ModelEncodingType.tabular_categorical:
|
|
@@ -413,9 +425,16 @@ def _analyze_reduce(
|
|
|
413
425
|
if encoding_type in _VALUE_PROTECTION_ENCODING_TYPES:
|
|
414
426
|
stats_col = {"value_protection": value_protection} | stats_col
|
|
415
427
|
|
|
416
|
-
|
|
417
|
-
if
|
|
418
|
-
|
|
428
|
+
is_ctxseq_column = "seq_len" in column_stats_list[0]
|
|
429
|
+
if is_ctxseq_column:
|
|
430
|
+
table_name = column.split(TABLE_COLUMN_INFIX)[0]
|
|
431
|
+
# only get the lengths from the first column of a ctxseq table and reuse the stats later
|
|
432
|
+
if table_name not in ctxseq_stats:
|
|
433
|
+
ctxseq_stats[table_name] = _analyze_reduce_seq_len(
|
|
434
|
+
stats_list=[column_stats_list[0]["seq_len"]], **value_protection_args
|
|
435
|
+
)
|
|
436
|
+
_LOG.info(f"analyzed sequence length for context table `{table_name}`")
|
|
437
|
+
stats_col["seq_len"] = ctxseq_stats[table_name]
|
|
419
438
|
|
|
420
439
|
is_language_column = encoding_type in (
|
|
421
440
|
ModelEncodingType.language_text,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/datetime.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/numeric.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/language/text.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/character.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/datetime.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/itt.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/lat_long.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_encoding_types/tabular/numeric.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/engine/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/engine/hf_engine.py
RENAMED
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/engine/vllm_engine.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mostlyai_engine-1.5.1 → mostlyai_engine-1.5.3}/mostlyai/engine/_language/tokenizer_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|