sdgym 0.15.1.dev0__tar.gz → 0.15.2.dev0__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.
- {sdgym-0.15.1.dev0/sdgym.egg-info → sdgym-0.15.2.dev0}/PKG-INFO +13 -5
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/pyproject.toml +14 -5
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/__init__.py +1 -1
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/utils.py +1 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizer_descriptions.yaml +11 -2
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/__init__.py +2 -0
- sdgym-0.15.2.dev0/sdgym/synthesizers/data_designer.py +346 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/realtabformer.py +14 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0/sdgym.egg-info}/PKG-INFO +13 -5
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym.egg-info/SOURCES.txt +1 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym.egg-info/requires.txt +14 -2
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/tests/test_tasks.py +1 -1
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/LICENSE +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/README.md +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark/__init__.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark/benchmark.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark/credentials_utils.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/__init__.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/_instance_manager.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/_storage_manager.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/_validation.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/benchmark_base.yaml +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/benchmark_config.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/benchmark_launcher.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_benchmark_launcher/script.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/_dataset_utils.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/benchmark.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/cli/__init__.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/cli/__main__.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/cli/collect.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/cli/summary.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/cli/utils.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/dataset_explorer.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/datasets.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/errors.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/metrics.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/progress.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/result_explorer/__init__.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/result_explorer/result_explorer.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/result_explorer/result_handler.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/result_writer.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/run_benchmark/__init__.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/run_benchmark/run_benchmark.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/run_benchmark/upload_benchmark_results.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/run_benchmark/utils.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/s3.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/base.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/clavaddpm.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/column.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/generate.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/identity.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/sdv.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/tabddpm.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/uniform.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/synthesizers/utils.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym/utils.py +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym.egg-info/dependency_links.txt +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym.egg-info/entry_points.txt +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/sdgym.egg-info/top_level.txt +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/setup.cfg +0 -0
- {sdgym-0.15.1.dev0 → sdgym-0.15.2.dev0}/tests/test_scripts.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdgym
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.2.dev0
|
|
4
4
|
Summary: Benchmark tabular synthetic data generators using a variety of datasets
|
|
5
5
|
Author-email: "DataCebo, Inc." <info@sdv.dev>
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -14,14 +14,13 @@ Classifier: Development Status :: 2 - Pre-Alpha
|
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.14
|
|
23
22
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
-
Requires-Python: <3.15,>=3.
|
|
23
|
+
Requires-Python: <3.15,>=3.10
|
|
25
24
|
Description-Content-Type: text/markdown
|
|
26
25
|
License-File: LICENSE
|
|
27
26
|
Requires-Dist: appdirs>=1.3
|
|
@@ -67,22 +66,31 @@ Requires-Dist: XlsxWriter>=1.2.8
|
|
|
67
66
|
Requires-Dist: rdt>=1.18.2; python_version < "3.14"
|
|
68
67
|
Requires-Dist: rdt>=1.20.0; python_version >= "3.14"
|
|
69
68
|
Requires-Dist: sdmetrics>=0.29.0
|
|
70
|
-
Requires-Dist: sdv
|
|
69
|
+
Requires-Dist: sdv<2,>=1.37.0
|
|
71
70
|
Provides-Extra: dask
|
|
72
71
|
Requires-Dist: dask; extra == "dask"
|
|
73
72
|
Requires-Dist: distributed; extra == "dask"
|
|
74
73
|
Provides-Extra: realtabformer
|
|
75
74
|
Requires-Dist: realtabformer!=0.2.4,>=0.2.3; extra == "realtabformer"
|
|
76
75
|
Requires-Dist: torch>=2.6.0; extra == "realtabformer"
|
|
77
|
-
Requires-Dist: transformers<4.51; extra == "realtabformer"
|
|
78
76
|
Provides-Extra: clavaddpm
|
|
79
77
|
Requires-Dist: faiss-cpu>=1.10.0; python_version < "3.14" and extra == "clavaddpm"
|
|
80
78
|
Requires-Dist: faiss-cpu>=1.12.0; python_version >= "3.14" and extra == "clavaddpm"
|
|
81
79
|
Requires-Dist: scipy>=1.9.2; extra == "clavaddpm"
|
|
82
80
|
Requires-Dist: numpy>=1.25.0; extra == "clavaddpm"
|
|
81
|
+
Provides-Extra: data-designer
|
|
82
|
+
Requires-Dist: data-designer>=0.8; python_version >= "3.10" and extra == "data-designer"
|
|
83
|
+
Requires-Dist: google-api-core<2.36; python_version >= "3.10" and extra == "data-designer"
|
|
84
|
+
Requires-Dist: pandas>=2.3.3; python_version >= "3.10" and extra == "data-designer"
|
|
85
|
+
Requires-Dist: scipy>=1.11.0; python_version >= "3.10" and extra == "data-designer"
|
|
86
|
+
Requires-Dist: transformers>=5.0.0; python_version >= "3.10" and extra == "data-designer"
|
|
87
|
+
Requires-Dist: boto3>=1.34.63; python_version >= "3.10" and extra == "data-designer"
|
|
88
|
+
Requires-Dist: botocore>=1.34.63; python_version >= "3.10" and extra == "data-designer"
|
|
89
|
+
Requires-Dist: pyOpenSSL>=26.4.0; python_version >= "3.10" and extra == "data-designer"
|
|
83
90
|
Provides-Extra: test
|
|
84
91
|
Requires-Dist: sdgym[realtabformer]; extra == "test"
|
|
85
92
|
Requires-Dist: sdgym[clavaddpm]; extra == "test"
|
|
93
|
+
Requires-Dist: sdgym[data_designer]; extra == "test"
|
|
86
94
|
Requires-Dist: pytest>=6.2.5; extra == "test"
|
|
87
95
|
Requires-Dist: pytest-cov>=2.6.0; extra == "test"
|
|
88
96
|
Requires-Dist: jupyter<2,>=1.0.0; extra == "test"
|
|
@@ -7,7 +7,6 @@ classifiers = [
|
|
|
7
7
|
'Intended Audience :: Developers',
|
|
8
8
|
'Natural Language :: English',
|
|
9
9
|
'Programming Language :: Python :: 3',
|
|
10
|
-
'Programming Language :: Python :: 3.9',
|
|
11
10
|
'Programming Language :: Python :: 3.10',
|
|
12
11
|
'Programming Language :: Python :: 3.11',
|
|
13
12
|
'Programming Language :: Python :: 3.12',
|
|
@@ -19,7 +18,7 @@ keywords = ['machine learning', 'synthetic data generation', 'benchmark', 'gener
|
|
|
19
18
|
dynamic = ['version']
|
|
20
19
|
license = 'BUSL-1.1'
|
|
21
20
|
license-files = ['LICENSE']
|
|
22
|
-
requires-python = '>=3.
|
|
21
|
+
requires-python = '>=3.10,<3.15'
|
|
23
22
|
readme = 'README.md'
|
|
24
23
|
dependencies = [
|
|
25
24
|
'appdirs>=1.3',
|
|
@@ -65,7 +64,7 @@ dependencies = [
|
|
|
65
64
|
"rdt>=1.18.2;python_version<'3.14'",
|
|
66
65
|
"rdt>=1.20.0;python_version>='3.14'",
|
|
67
66
|
"sdmetrics>=0.29.0",
|
|
68
|
-
"sdv>=1.37.0",
|
|
67
|
+
"sdv>=1.37.0,<2",
|
|
69
68
|
]
|
|
70
69
|
|
|
71
70
|
[project.urls]
|
|
@@ -83,7 +82,6 @@ dask = ['dask', 'distributed']
|
|
|
83
82
|
realtabformer = [
|
|
84
83
|
'realtabformer>=0.2.3,!=0.2.4',
|
|
85
84
|
"torch>=2.6.0",
|
|
86
|
-
'transformers<4.51',
|
|
87
85
|
]
|
|
88
86
|
clavaddpm = [
|
|
89
87
|
"faiss-cpu>=1.10.0;python_version<'3.14'",
|
|
@@ -91,9 +89,20 @@ clavaddpm = [
|
|
|
91
89
|
'scipy>=1.9.2',
|
|
92
90
|
'numpy>=1.25.0',
|
|
93
91
|
]
|
|
92
|
+
data_designer = [
|
|
93
|
+
"data-designer>=0.8;python_version>='3.10'",
|
|
94
|
+
"google-api-core<2.36;python_version>='3.10'", # requires opentelemetry-api<1.44
|
|
95
|
+
"pandas>=2.3.3;python_version>='3.10'",
|
|
96
|
+
"scipy>=1.11.0;python_version>='3.10'",
|
|
97
|
+
"transformers>=5.0.0;python_version>='3.10'", # requires huggingface-hub>=1
|
|
98
|
+
"boto3>=1.34.63;python_version>='3.10'", # requires urllib3>=2.7
|
|
99
|
+
"botocore>=1.34.63;python_version>='3.10'",
|
|
100
|
+
"pyOpenSSL>=26.4.0;python_version>='3.10'", # requires cryptography>=48
|
|
101
|
+
]
|
|
94
102
|
test = [
|
|
95
103
|
'sdgym[realtabformer]',
|
|
96
104
|
'sdgym[clavaddpm]',
|
|
105
|
+
'sdgym[data_designer]',
|
|
97
106
|
'pytest>=6.2.5',
|
|
98
107
|
'pytest-cov>=2.6.0',
|
|
99
108
|
'jupyter>=1.0.0,<2',
|
|
@@ -168,7 +177,7 @@ namespaces = false
|
|
|
168
177
|
version = {attr = 'sdgym.__version__'}
|
|
169
178
|
|
|
170
179
|
[tool.bumpversion]
|
|
171
|
-
current_version = "0.15.
|
|
180
|
+
current_version = "0.15.2.dev0"
|
|
172
181
|
parse = '(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.(?P<release>[a-z]+)(?P<candidate>\d+))?'
|
|
173
182
|
serialize = [
|
|
174
183
|
'{major}.{minor}.{patch}.{release}{candidate}',
|
|
@@ -134,7 +134,7 @@ XGCSynthesizer:
|
|
|
134
134
|
to train a model and generate synthetic data similar to the GaussianCopulaSynthesizer.
|
|
135
135
|
However, it contains some additional features for higher quality modeling.
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
TabDDPMSynthesizer:
|
|
138
138
|
library: sdgym
|
|
139
139
|
organization: Yandex
|
|
140
140
|
modality: single_table
|
|
@@ -152,4 +152,13 @@ ClavaDDPMSynthesizer:
|
|
|
152
152
|
description: >
|
|
153
153
|
The ClavaDDPM model is an extension of the TabDDPM model to handle multi-table datasets.
|
|
154
154
|
It is based on clustering labels as intermediaries to model relationships between tables,
|
|
155
|
-
specifically focusing on foreign key constraints.
|
|
155
|
+
specifically focusing on foreign key constraints.
|
|
156
|
+
|
|
157
|
+
DataDesignerSynthesizer:
|
|
158
|
+
library: data-designer
|
|
159
|
+
organization: Nvidia
|
|
160
|
+
modality: single_table
|
|
161
|
+
type: Statistical and Large Language Models
|
|
162
|
+
description: >
|
|
163
|
+
NVIDIA Data Designer is a configurable framework that uses LLMs, statistical models,
|
|
164
|
+
and customizable samplers to generate synthetic data.
|
|
@@ -7,6 +7,7 @@ from sdgym.synthesizers.generate import (
|
|
|
7
7
|
)
|
|
8
8
|
from sdgym.synthesizers.identity import DataIdentity
|
|
9
9
|
from sdgym.synthesizers.column import ColumnSynthesizer
|
|
10
|
+
from sdgym.synthesizers.data_designer import DataDesignerSynthesizer
|
|
10
11
|
from sdgym.synthesizers.realtabformer import RealTabFormerSynthesizer
|
|
11
12
|
from sdgym.synthesizers.tabddpm import TabDDPMSynthesizer
|
|
12
13
|
from sdgym.synthesizers.clavaddpm import ClavaDDPMSynthesizer
|
|
@@ -21,6 +22,7 @@ from sdgym.synthesizers.sdv import create_sdv_synthesizer_class, _get_all_sdv_sy
|
|
|
21
22
|
__all__ = [
|
|
22
23
|
'DataIdentity',
|
|
23
24
|
'ColumnSynthesizer',
|
|
25
|
+
'DataDesignerSynthesizer',
|
|
24
26
|
'UniformSynthesizer',
|
|
25
27
|
'RealTabFormerSynthesizer',
|
|
26
28
|
'TabDDPMSynthesizer',
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
"""NVIDIA Data Designer integration."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import shutil
|
|
5
|
+
import sys
|
|
6
|
+
import tempfile
|
|
7
|
+
import uuid
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
import pandas as pd
|
|
12
|
+
from sdv.metadata import Metadata
|
|
13
|
+
|
|
14
|
+
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
15
|
+
|
|
16
|
+
LOGGER = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
MIN_PYTHON_VERSION = (3, 10)
|
|
19
|
+
DEFAULT_MODEL_ALIAS = 'text'
|
|
20
|
+
DEFAULT_MODEL_ID = 'nvidia/nvidia-nemotron-nano-9b-v2'
|
|
21
|
+
DEFAULT_MODEL_PROVIDER = 'nvidia'
|
|
22
|
+
DEFAULT_TEMPERATURE = 0.85
|
|
23
|
+
DEFAULT_TOP_P = 0.95
|
|
24
|
+
PII_PLACEHOLDER_PREFIX = 'sdgym-pii-'
|
|
25
|
+
MAX_TEXT_EXAMPLES = 3
|
|
26
|
+
MAX_TEXT_EXAMPLE_LENGTH = 100
|
|
27
|
+
|
|
28
|
+
MISSING_PROPORTION_ATTRIBUTES = (
|
|
29
|
+
'missing_values_proportion',
|
|
30
|
+
'missing_proportion',
|
|
31
|
+
'null_proportion',
|
|
32
|
+
)
|
|
33
|
+
# sdtypes that can be useful as context
|
|
34
|
+
TEXT_CONTEXT_SDTYPES = {'numerical', 'categorical', 'boolean', 'datetime'}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _import_data_designer():
|
|
38
|
+
if sys.version_info < MIN_PYTHON_VERSION:
|
|
39
|
+
raise ImportError('DataDesignerSynthesizer only supports python >= 3.10')
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
import data_designer.config as data_designer_config
|
|
43
|
+
except ImportError as exception:
|
|
44
|
+
raise ImportError(
|
|
45
|
+
"To use 'DataDesignerSynthesizer' you have to install the extra "
|
|
46
|
+
"dependencies by running pip install sdgym['data_designer']"
|
|
47
|
+
) from exception
|
|
48
|
+
|
|
49
|
+
return data_designer_config
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _get_table_metadata(metadata, table_name=None):
|
|
53
|
+
"""Return the metadata of ``table_name`` from a ``Metadata`` object."""
|
|
54
|
+
if not isinstance(metadata, Metadata):
|
|
55
|
+
raise TypeError(f'Expected sdv.Metadata, got {type(metadata).__name__}. ')
|
|
56
|
+
|
|
57
|
+
if table_name is None:
|
|
58
|
+
if len(metadata.tables) != 1:
|
|
59
|
+
raise ValueError(
|
|
60
|
+
f'Metadata has {len(metadata.tables)} tables, please provide a `table_name`. '
|
|
61
|
+
'DataDesignerSynthesizer only supports single table metadata.'
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
table_name = metadata._get_single_table_name()
|
|
65
|
+
|
|
66
|
+
if table_name not in metadata.tables:
|
|
67
|
+
raise ValueError(f"Table '{table_name}' is not present in the metadata.")
|
|
68
|
+
|
|
69
|
+
return metadata.tables[table_name]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _create_default_model_config(
|
|
73
|
+
dd,
|
|
74
|
+
model_alias,
|
|
75
|
+
model=DEFAULT_MODEL_ID,
|
|
76
|
+
provider=DEFAULT_MODEL_PROVIDER,
|
|
77
|
+
temperature=DEFAULT_TEMPERATURE,
|
|
78
|
+
top_p=DEFAULT_TOP_P,
|
|
79
|
+
):
|
|
80
|
+
|
|
81
|
+
return dd.ModelConfig(
|
|
82
|
+
alias=model_alias,
|
|
83
|
+
model=model,
|
|
84
|
+
provider=provider,
|
|
85
|
+
inference_parameters=dd.ChatCompletionInferenceParams(temperature=temperature, top_p=top_p),
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _create_categorical_config(dd, column_name, column_data, column_metadata):
|
|
90
|
+
"""Map a categorical column to a weighted ``category`` sampler."""
|
|
91
|
+
value_counts = column_data.dropna().value_counts()
|
|
92
|
+
values = column_metadata.get('range_values')
|
|
93
|
+
if values is None:
|
|
94
|
+
values = list(value_counts.index)
|
|
95
|
+
|
|
96
|
+
if not values:
|
|
97
|
+
LOGGER.warning(
|
|
98
|
+
f"Column '{column_name}' has no observed values, using a placeholder sampler."
|
|
99
|
+
)
|
|
100
|
+
return _create_placeholder_config(dd, column_name)
|
|
101
|
+
|
|
102
|
+
values = [value.item() if isinstance(value, np.generic) else value for value in values]
|
|
103
|
+
weights = [float(value_counts.get(value, 0)) for value in values]
|
|
104
|
+
params = dd.CategorySamplerParams(values=values, weights=weights if sum(weights) else None)
|
|
105
|
+
return dd.SamplerColumnConfig(
|
|
106
|
+
name=column_name, sampler_type=dd.SamplerType.CATEGORY, params=params
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _create_boolean_config(dd, column_name, column_data):
|
|
111
|
+
"""Map a boolean column to a ``bernoulli`` sampler."""
|
|
112
|
+
values = column_data.dropna()
|
|
113
|
+
probability = float(values.astype(bool).mean()) if not values.empty else 0.5
|
|
114
|
+
params = dd.BernoulliSamplerParams(p=probability)
|
|
115
|
+
return dd.SamplerColumnConfig(
|
|
116
|
+
name=column_name, sampler_type=dd.SamplerType.BERNOULLI, params=params
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def _get_decimal_places(values):
|
|
121
|
+
"""Return the largest number of decimal places observed in ``values``."""
|
|
122
|
+
decimals = 0
|
|
123
|
+
for value in values.head(1000):
|
|
124
|
+
_, _, fraction = repr(float(value)).partition('.')
|
|
125
|
+
if fraction and fraction != '0':
|
|
126
|
+
decimals = max(decimals, len(fraction))
|
|
127
|
+
|
|
128
|
+
return decimals
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def _create_numerical_config(dd, column_name, column_data, column_metadata):
|
|
132
|
+
"""Map a numerical column to a ``uniform`` sampler."""
|
|
133
|
+
values = pd.to_numeric(column_data, errors='coerce').dropna()
|
|
134
|
+
values_empty = values.empty
|
|
135
|
+
has_range = 'range_min' in column_metadata and 'range_max' in column_metadata
|
|
136
|
+
if values_empty and not has_range:
|
|
137
|
+
LOGGER.warning(
|
|
138
|
+
f"Column '{column_name}' has no numeric values, sampling from normal distribution."
|
|
139
|
+
)
|
|
140
|
+
return dd.SamplerColumnConfig(
|
|
141
|
+
name=column_name,
|
|
142
|
+
sampler_type=dd.SamplerType.GAUSSIAN,
|
|
143
|
+
params=dd.GaussianSamplerParams(mean=0, stddev=1),
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
low = column_metadata.get('range_min', values.min())
|
|
147
|
+
high = column_metadata.get('range_max', values.max())
|
|
148
|
+
decimal_places = column_metadata.get('decimal_places', _get_decimal_places(values))
|
|
149
|
+
is_integer = decimal_places == 0
|
|
150
|
+
|
|
151
|
+
params = dd.UniformSamplerParams(
|
|
152
|
+
low=float(low), high=float(high), decimal_places=decimal_places
|
|
153
|
+
)
|
|
154
|
+
return dd.SamplerColumnConfig(
|
|
155
|
+
name=column_name,
|
|
156
|
+
sampler_type=dd.SamplerType.UNIFORM,
|
|
157
|
+
params=params,
|
|
158
|
+
convert_to='int' if is_integer else None,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def _create_datetime_config(dd, column_name, column_data, column_metadata):
|
|
163
|
+
"""Map a datetime column to a ``datetime`` sampler."""
|
|
164
|
+
datetime_format = column_metadata.get('datetime_format')
|
|
165
|
+
values = pd.to_datetime(column_data, format=datetime_format, errors='coerce').dropna()
|
|
166
|
+
start = pd.to_datetime(column_metadata.get('range_min', values.min()), format=datetime_format)
|
|
167
|
+
end = pd.to_datetime(column_metadata.get('range_max', values.max()), format=datetime_format)
|
|
168
|
+
|
|
169
|
+
if pd.isna(start) and pd.isna(end):
|
|
170
|
+
LOGGER.warning(
|
|
171
|
+
f"Column '{column_name}' has no parseable datetimes, using a placeholder sampler."
|
|
172
|
+
)
|
|
173
|
+
return _create_placeholder_config(dd, column_name)
|
|
174
|
+
|
|
175
|
+
elif pd.isna(start):
|
|
176
|
+
start = end
|
|
177
|
+
elif pd.isna(end):
|
|
178
|
+
end = start
|
|
179
|
+
|
|
180
|
+
output_format = datetime_format or '%Y-%m-%d %H:%M:%S'
|
|
181
|
+
params = dd.DatetimeSamplerParams(
|
|
182
|
+
start=start.strftime(output_format), end=end.strftime(output_format)
|
|
183
|
+
)
|
|
184
|
+
return dd.SamplerColumnConfig(
|
|
185
|
+
name=column_name, sampler_type=dd.SamplerType.DATETIME, params=params
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _create_id_config(dd, column_name):
|
|
190
|
+
"""Map an id column to a ``uuid`` sampler, no other id sampler is available."""
|
|
191
|
+
return dd.SamplerColumnConfig(
|
|
192
|
+
name=column_name, sampler_type=dd.SamplerType.UUID, params=dd.UUIDSamplerParams()
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _create_placeholder_config(dd, column_name):
|
|
197
|
+
"""Map unknown or unsupported pii columns to short anonymized placeholders."""
|
|
198
|
+
params = dd.UUIDSamplerParams(prefix=PII_PLACEHOLDER_PREFIX, short_form=True)
|
|
199
|
+
return dd.SamplerColumnConfig(name=column_name, sampler_type=dd.SamplerType.UUID, params=params)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def _create_text_config(dd, column_name, column_data, model_alias, context_columns):
|
|
203
|
+
"""Map a text column to an LLM generated column conditioned on the rest of the row."""
|
|
204
|
+
examples = []
|
|
205
|
+
for value in column_data.dropna().astype(str).unique()[:MAX_TEXT_EXAMPLES]:
|
|
206
|
+
examples.append(repr(value[:MAX_TEXT_EXAMPLE_LENGTH]))
|
|
207
|
+
|
|
208
|
+
prompt = (
|
|
209
|
+
'You are a helpful assistant that generates synthetic data.'
|
|
210
|
+
f"Generate a realistic value for the column '{column_name}' of a tabular dataset."
|
|
211
|
+
)
|
|
212
|
+
if examples:
|
|
213
|
+
prompt += f' Here are a few examples from this column: {", ".join(examples)}.'
|
|
214
|
+
|
|
215
|
+
if context_columns:
|
|
216
|
+
row = ', '.join(f'{{ {name} }}' for name in context_columns)
|
|
217
|
+
prompt += f' Refer to the values in these columns for context: {row}.'
|
|
218
|
+
|
|
219
|
+
prompt += ' Respond with the value only, without any explanation.'
|
|
220
|
+
return dd.LLMTextColumnConfig(name=column_name, prompt=prompt, model_alias=model_alias)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def create_data_designer_config(
|
|
224
|
+
data,
|
|
225
|
+
metadata,
|
|
226
|
+
table_name=None,
|
|
227
|
+
model_alias=DEFAULT_MODEL_ALIAS,
|
|
228
|
+
model=DEFAULT_MODEL_ID,
|
|
229
|
+
provider=DEFAULT_MODEL_PROVIDER,
|
|
230
|
+
temperature=DEFAULT_TEMPERATURE,
|
|
231
|
+
top_p=DEFAULT_TOP_P,
|
|
232
|
+
):
|
|
233
|
+
"""Map a single table dataset and its metadata to a Data Designer config builder.
|
|
234
|
+
|
|
235
|
+
Args:
|
|
236
|
+
data (pd.DataFrame):
|
|
237
|
+
The real data. Used to fit the sampler parameters that the metadata does not
|
|
238
|
+
provide (frequencies, ranges, boolean rates) and to pick text examples.
|
|
239
|
+
metadata (sdv.Metadata):
|
|
240
|
+
Metadata describing the data. If range values are not present, they are
|
|
241
|
+
extracted directly from data.
|
|
242
|
+
table_name (str or None):
|
|
243
|
+
The table to map when the metadata has more than one table. Defaults to the only
|
|
244
|
+
table.
|
|
245
|
+
model_alias (str):
|
|
246
|
+
The model alias used by LLM generated text columns. Defaults to 'text'.
|
|
247
|
+
model (str):
|
|
248
|
+
The model identifier used for inference. This must correspond to the
|
|
249
|
+
served model name configured by the specified provider.
|
|
250
|
+
provider (str):
|
|
251
|
+
The provider identifier used to route inference requests to the specified model.
|
|
252
|
+
temperature (float):
|
|
253
|
+
Sampling temperature of the model used by LLM generated text columns. Higher
|
|
254
|
+
values produce more varied text. Defaults to 0.85.
|
|
255
|
+
top_p (float):
|
|
256
|
+
Nucleus sampling probability of the model used by LLM generated text columns.
|
|
257
|
+
Defaults to 0.95.
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
DataDesignerConfigBuilder:
|
|
261
|
+
A builder holding one column config per metadata column.
|
|
262
|
+
"""
|
|
263
|
+
dd = _import_data_designer()
|
|
264
|
+
table_metadata = _get_table_metadata(metadata, table_name)
|
|
265
|
+
model_configs = [
|
|
266
|
+
_create_default_model_config(dd, model_alias, model, provider, temperature, top_p)
|
|
267
|
+
]
|
|
268
|
+
|
|
269
|
+
context_columns = [
|
|
270
|
+
name
|
|
271
|
+
for name, column_meta in table_metadata.columns.items()
|
|
272
|
+
if column_meta['sdtype'] in TEXT_CONTEXT_SDTYPES
|
|
273
|
+
]
|
|
274
|
+
|
|
275
|
+
column_configs = []
|
|
276
|
+
for column_name, column_metadata in table_metadata.columns.items():
|
|
277
|
+
sdtype = column_metadata['sdtype']
|
|
278
|
+
column_data = data[column_name]
|
|
279
|
+
if sdtype == 'boolean':
|
|
280
|
+
config = _create_boolean_config(dd, column_name, column_data)
|
|
281
|
+
elif sdtype == 'numerical':
|
|
282
|
+
config = _create_numerical_config(dd, column_name, column_data, column_metadata)
|
|
283
|
+
elif sdtype == 'datetime':
|
|
284
|
+
config = _create_datetime_config(dd, column_name, column_data, column_metadata)
|
|
285
|
+
elif sdtype == 'id':
|
|
286
|
+
config = _create_id_config(dd, column_name)
|
|
287
|
+
elif sdtype == 'text':
|
|
288
|
+
config = _create_text_config(dd, column_name, column_data, model_alias, context_columns)
|
|
289
|
+
else:
|
|
290
|
+
config = _create_categorical_config(dd, column_name, column_data, column_metadata)
|
|
291
|
+
|
|
292
|
+
column_configs.append(config)
|
|
293
|
+
|
|
294
|
+
builder = dd.DataDesignerConfigBuilder(model_configs=model_configs)
|
|
295
|
+
for config in column_configs:
|
|
296
|
+
builder.add_column(config)
|
|
297
|
+
|
|
298
|
+
return builder
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
class DataDesignerSynthesizer(BaselineSynthesizer):
|
|
302
|
+
"""Custom wrapper for the DataDesigner synthesizer to make it work with SDGym."""
|
|
303
|
+
|
|
304
|
+
LOGGER = logging.getLogger(__name__)
|
|
305
|
+
_MODEL_KWARGS = None
|
|
306
|
+
_MODALITY_FLAG = 'single_table'
|
|
307
|
+
|
|
308
|
+
def _fit(self, data, metadata):
|
|
309
|
+
table_name = metadata._get_single_table_name()
|
|
310
|
+
metadata.validate()
|
|
311
|
+
metadata.validate_data({table_name: data})
|
|
312
|
+
|
|
313
|
+
model_kwargs = self._MODEL_KWARGS.copy() if self._MODEL_KWARGS else {}
|
|
314
|
+
self._artifact_path = model_kwargs.pop('artifact_path', None)
|
|
315
|
+
self._cleanup_artifacts = model_kwargs.pop('cleanup_artifacts', True)
|
|
316
|
+
self._config_builder = create_data_designer_config(data, metadata, **model_kwargs)
|
|
317
|
+
|
|
318
|
+
def _sample_from_synthesizer(self, synthesizer, n_sample):
|
|
319
|
+
"""Sample synthetic data with specified sample count."""
|
|
320
|
+
try:
|
|
321
|
+
from data_designer.interface import DataDesigner
|
|
322
|
+
except Exception as exception:
|
|
323
|
+
raise ImportError(
|
|
324
|
+
"To use 'DataDesignerSynthesizer' you have to install the extra "
|
|
325
|
+
"dependencies by running pip install sdgym['data_designer']"
|
|
326
|
+
) from exception
|
|
327
|
+
|
|
328
|
+
is_temporary = synthesizer._artifact_path is None
|
|
329
|
+
if is_temporary:
|
|
330
|
+
artifact_path = Path(tempfile.mkdtemp(prefix='sdgym-data-designer-'))
|
|
331
|
+
else:
|
|
332
|
+
artifact_path = Path(synthesizer._artifact_path)
|
|
333
|
+
|
|
334
|
+
# A unique name keeps concurrent or repeated sample calls from sharing a folder.
|
|
335
|
+
dataset_name = f'dataset-{uuid.uuid4().hex}'
|
|
336
|
+
try:
|
|
337
|
+
output = DataDesigner(artifact_path=artifact_path).create(
|
|
338
|
+
synthesizer._config_builder, num_records=n_sample, dataset_name=dataset_name
|
|
339
|
+
)
|
|
340
|
+
return output.load_dataset()
|
|
341
|
+
finally:
|
|
342
|
+
if synthesizer._cleanup_artifacts:
|
|
343
|
+
to_remove = artifact_path if is_temporary else artifact_path / dataset_name
|
|
344
|
+
shutil.rmtree(to_remove, ignore_errors=True)
|
|
345
|
+
else:
|
|
346
|
+
self.LOGGER.info(f'Data Designer artifacts kept in {artifact_path / dataset_name}')
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""REaLTabFormer integration."""
|
|
2
2
|
|
|
3
3
|
import contextlib
|
|
4
|
+
import dataclasses
|
|
4
5
|
import logging
|
|
5
6
|
from functools import partialmethod
|
|
6
7
|
|
|
@@ -8,6 +9,8 @@ import tqdm
|
|
|
8
9
|
|
|
9
10
|
from sdgym.synthesizers.base import BaselineSynthesizer
|
|
10
11
|
|
|
12
|
+
REMOVED_TRAINING_ARGS = ('overwrite_output_dir',)
|
|
13
|
+
|
|
11
14
|
|
|
12
15
|
@contextlib.contextmanager
|
|
13
16
|
def prevent_tqdm_output():
|
|
@@ -19,6 +22,16 @@ def prevent_tqdm_output():
|
|
|
19
22
|
tqdm.__init__ = partialmethod(tqdm.__init__, disable=False)
|
|
20
23
|
|
|
21
24
|
|
|
25
|
+
def _remove_unsupported_training_args(model):
|
|
26
|
+
"""Drop deprecated args that are no longer used by transformers."""
|
|
27
|
+
from transformers import TrainingArguments
|
|
28
|
+
|
|
29
|
+
supported = {field.name for field in dataclasses.fields(TrainingArguments)}
|
|
30
|
+
for name in REMOVED_TRAINING_ARGS:
|
|
31
|
+
if name not in supported:
|
|
32
|
+
model.training_args_kwargs.pop(name, None)
|
|
33
|
+
|
|
34
|
+
|
|
22
35
|
class RealTabFormerSynthesizer(BaselineSynthesizer):
|
|
23
36
|
"""Custom wrapper for the REaLTabFormer synthesizer to make it work with SDGym."""
|
|
24
37
|
|
|
@@ -39,6 +52,7 @@ class RealTabFormerSynthesizer(BaselineSynthesizer):
|
|
|
39
52
|
with prevent_tqdm_output():
|
|
40
53
|
model_kwargs = self._MODEL_KWARGS.copy() if self._MODEL_KWARGS else {}
|
|
41
54
|
model = REaLTabFormer(model_type='tabular', **model_kwargs)
|
|
55
|
+
_remove_unsupported_training_args(model)
|
|
42
56
|
model.fit(data)
|
|
43
57
|
|
|
44
58
|
self._internal_synthesizer = model
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdgym
|
|
3
|
-
Version: 0.15.
|
|
3
|
+
Version: 0.15.2.dev0
|
|
4
4
|
Summary: Benchmark tabular synthetic data generators using a variety of datasets
|
|
5
5
|
Author-email: "DataCebo, Inc." <info@sdv.dev>
|
|
6
6
|
License-Expression: BUSL-1.1
|
|
@@ -14,14 +14,13 @@ Classifier: Development Status :: 2 - Pre-Alpha
|
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Natural Language :: English
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.14
|
|
23
22
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
-
Requires-Python: <3.15,>=3.
|
|
23
|
+
Requires-Python: <3.15,>=3.10
|
|
25
24
|
Description-Content-Type: text/markdown
|
|
26
25
|
License-File: LICENSE
|
|
27
26
|
Requires-Dist: appdirs>=1.3
|
|
@@ -67,22 +66,31 @@ Requires-Dist: XlsxWriter>=1.2.8
|
|
|
67
66
|
Requires-Dist: rdt>=1.18.2; python_version < "3.14"
|
|
68
67
|
Requires-Dist: rdt>=1.20.0; python_version >= "3.14"
|
|
69
68
|
Requires-Dist: sdmetrics>=0.29.0
|
|
70
|
-
Requires-Dist: sdv
|
|
69
|
+
Requires-Dist: sdv<2,>=1.37.0
|
|
71
70
|
Provides-Extra: dask
|
|
72
71
|
Requires-Dist: dask; extra == "dask"
|
|
73
72
|
Requires-Dist: distributed; extra == "dask"
|
|
74
73
|
Provides-Extra: realtabformer
|
|
75
74
|
Requires-Dist: realtabformer!=0.2.4,>=0.2.3; extra == "realtabformer"
|
|
76
75
|
Requires-Dist: torch>=2.6.0; extra == "realtabformer"
|
|
77
|
-
Requires-Dist: transformers<4.51; extra == "realtabformer"
|
|
78
76
|
Provides-Extra: clavaddpm
|
|
79
77
|
Requires-Dist: faiss-cpu>=1.10.0; python_version < "3.14" and extra == "clavaddpm"
|
|
80
78
|
Requires-Dist: faiss-cpu>=1.12.0; python_version >= "3.14" and extra == "clavaddpm"
|
|
81
79
|
Requires-Dist: scipy>=1.9.2; extra == "clavaddpm"
|
|
82
80
|
Requires-Dist: numpy>=1.25.0; extra == "clavaddpm"
|
|
81
|
+
Provides-Extra: data-designer
|
|
82
|
+
Requires-Dist: data-designer>=0.8; python_version >= "3.10" and extra == "data-designer"
|
|
83
|
+
Requires-Dist: google-api-core<2.36; python_version >= "3.10" and extra == "data-designer"
|
|
84
|
+
Requires-Dist: pandas>=2.3.3; python_version >= "3.10" and extra == "data-designer"
|
|
85
|
+
Requires-Dist: scipy>=1.11.0; python_version >= "3.10" and extra == "data-designer"
|
|
86
|
+
Requires-Dist: transformers>=5.0.0; python_version >= "3.10" and extra == "data-designer"
|
|
87
|
+
Requires-Dist: boto3>=1.34.63; python_version >= "3.10" and extra == "data-designer"
|
|
88
|
+
Requires-Dist: botocore>=1.34.63; python_version >= "3.10" and extra == "data-designer"
|
|
89
|
+
Requires-Dist: pyOpenSSL>=26.4.0; python_version >= "3.10" and extra == "data-designer"
|
|
83
90
|
Provides-Extra: test
|
|
84
91
|
Requires-Dist: sdgym[realtabformer]; extra == "test"
|
|
85
92
|
Requires-Dist: sdgym[clavaddpm]; extra == "test"
|
|
93
|
+
Requires-Dist: sdgym[data_designer]; extra == "test"
|
|
86
94
|
Requires-Dist: pytest>=6.2.5; extra == "test"
|
|
87
95
|
Requires-Dist: pytest-cov>=2.6.0; extra == "test"
|
|
88
96
|
Requires-Dist: jupyter<2,>=1.0.0; extra == "test"
|
|
@@ -47,6 +47,7 @@ sdgym/synthesizers/__init__.py
|
|
|
47
47
|
sdgym/synthesizers/base.py
|
|
48
48
|
sdgym/synthesizers/clavaddpm.py
|
|
49
49
|
sdgym/synthesizers/column.py
|
|
50
|
+
sdgym/synthesizers/data_designer.py
|
|
50
51
|
sdgym/synthesizers/generate.py
|
|
51
52
|
sdgym/synthesizers/identity.py
|
|
52
53
|
sdgym/synthesizers/realtabformer.py
|
|
@@ -11,7 +11,7 @@ tabulate<0.9,>=0.8.3
|
|
|
11
11
|
tqdm>=4.66.3
|
|
12
12
|
XlsxWriter>=1.2.8
|
|
13
13
|
sdmetrics>=0.29.0
|
|
14
|
-
sdv
|
|
14
|
+
sdv<2,>=1.37.0
|
|
15
15
|
|
|
16
16
|
[:python_version < "3.10"]
|
|
17
17
|
numpy>=1.22.2
|
|
@@ -78,6 +78,18 @@ faiss-cpu>=1.12.0
|
|
|
78
78
|
dask
|
|
79
79
|
distributed
|
|
80
80
|
|
|
81
|
+
[data_designer]
|
|
82
|
+
|
|
83
|
+
[data_designer:python_version >= "3.10"]
|
|
84
|
+
data-designer>=0.8
|
|
85
|
+
google-api-core<2.36
|
|
86
|
+
pandas>=2.3.3
|
|
87
|
+
scipy>=1.11.0
|
|
88
|
+
transformers>=5.0.0
|
|
89
|
+
boto3>=1.34.63
|
|
90
|
+
botocore>=1.34.63
|
|
91
|
+
pyOpenSSL>=26.4.0
|
|
92
|
+
|
|
81
93
|
[dev]
|
|
82
94
|
sdgym[dask,test]
|
|
83
95
|
build<2,>=1.0.0
|
|
@@ -97,11 +109,11 @@ rundoc<0.5,>=0.4.3
|
|
|
97
109
|
[realtabformer]
|
|
98
110
|
realtabformer!=0.2.4,>=0.2.3
|
|
99
111
|
torch>=2.6.0
|
|
100
|
-
transformers<4.51
|
|
101
112
|
|
|
102
113
|
[test]
|
|
103
114
|
sdgym[realtabformer]
|
|
104
115
|
sdgym[clavaddpm]
|
|
116
|
+
sdgym[data_designer]
|
|
105
117
|
pytest>=6.2.5
|
|
106
118
|
pytest-cov>=2.6.0
|
|
107
119
|
jupyter<2,>=1.0.0
|
|
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
|
|
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
|
|
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
|