-
Notifications
You must be signed in to change notification settings - Fork 69
Move the current benchmark configs to yaml files #566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
R-Palazzo
merged 21 commits into
feature/benchmark_launcher
from
issue-532-define-yaml-files
Mar 17, 2026
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
706fc74
progress 545
R-Palazzo af06677
progress
R-Palazzo 4fa0081
progress 2
R-Palazzo 952dd7b
progress 3
R-Palazzo 19404a7
progress 4
R-Palazzo 50af9ee
progress 5
R-Palazzo 39623ad
progress 6
R-Palazzo c4edfa5
progress 7
R-Palazzo f670ba5
cleaning
R-Palazzo 1a5ef6f
address comments
R-Palazzo df742dd
fix tests
R-Palazzo 612c429
update
R-Palazzo e6b57fc
fix test
R-Palazzo 5c42adb
update pyproject
R-Palazzo 629b80c
fix credential handling
R-Palazzo 133a551
remove method parameter check
R-Palazzo 28bffd6
test end to end
R-Palazzo 9ae9629
fix
R-Palazzo 36957fd
move output_destination to instance_jobs
R-Palazzo 0b07c0c
address comments
R-Palazzo 7f06606
fix yaml files
R-Palazzo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| """Benchmark Launcher Module.""" | ||
|
|
||
| from sdgym._benchmark_launcher.benchmark_config import BenchmarkConfig | ||
| from sdgym._benchmark_launcher.benchmark_launcher import BenchmarkLauncher | ||
|
|
||
| __all__ = ('BenchmarkConfig', 'BenchmarkLauncher') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,193 @@ | ||
| from sdgym._benchmark_launcher.utils import ( | ||
| _AWS_CREDENTIAL_KEYS, | ||
| _GCP_SERVICE_ACCOUNT_REQUIRED_KEYS, | ||
| resolve_credentials, | ||
| ) | ||
|
|
||
| _INJECTED_PARAMS = { | ||
| 'credentials', | ||
| 'synthesizers', | ||
| 'sdv_datasets', | ||
| 'compute_config', | ||
| 'output_destination', | ||
| } | ||
|
|
||
|
|
||
| def _as_errors(value): | ||
| if value is None: | ||
| return [] | ||
| if isinstance(value, list): | ||
| return [str(v) for v in value if v] | ||
|
|
||
| return [str(value)] | ||
|
|
||
|
|
||
| def _format_sectioned_errors(section_errors): | ||
| parts = ['BenchmarkConfig validation failed:\n'] | ||
| for section, raw in section_errors.items(): | ||
| errs = _as_errors(raw) | ||
| if not errs: | ||
| continue | ||
| parts.append(f'[{section}]') | ||
| parts.extend([f'- {e}' for e in errs]) | ||
| parts.append('') | ||
|
|
||
| return '\n'.join(parts).rstrip() | ||
|
|
||
|
|
||
| def _validate_structure(config): | ||
| errors = [] | ||
| if config.modality not in ('single_table', 'multi_table'): | ||
| errors.append( | ||
| f"modality: must be 'single_table' or 'multi_table'. Found: {config.modality!r}" | ||
| ) | ||
|
|
||
| if config.credentials_filepath is not None and not isinstance(config.credentials_filepath, str): | ||
| errors.append('credentials_filepath must be a string or None.') | ||
|
|
||
| expected_types = { | ||
| 'method_params': dict, | ||
| 'compute': dict, | ||
| 'instance_jobs': list, | ||
| } | ||
| for key, expected_type in expected_types.items(): | ||
| value = getattr(config, key, None) | ||
| if value is None: | ||
| errors.append(f'{key}: is a required section but missing.') | ||
| elif not isinstance(value, expected_type): | ||
| errors.append(f'{key}: must be a {expected_type.__name__}. Found: {type(value)}') | ||
|
|
||
| compute = getattr(config, 'compute', None) | ||
| if isinstance(compute, dict): | ||
| service = compute.get('service') | ||
| if service not in ('gcp',): | ||
| errors.append(f"compute.service: must be 'gcp'. Found: {service!r}") | ||
|
|
||
| return sorted(errors) | ||
|
|
||
|
|
||
| def _validate_method_params(method_params, method_to_run): | ||
| errors = [] | ||
| timeout = method_params.get('timeout') | ||
| if timeout is not None: | ||
| if not isinstance(timeout, int): | ||
| errors.append( | ||
| f'method_params.timeout: must be int seconds. Found: {timeout!r} ({type(timeout)})' | ||
| ) | ||
| elif timeout <= 0: | ||
| errors.append('method_params.timeout: must be > 0.') | ||
|
|
||
| for key in ('compute_quality_score', 'compute_diagnostic_score', 'compute_privacy_score'): | ||
| value = method_params.get(key) | ||
| if value is not None and not isinstance(value, bool): | ||
| errors.append(f'method_params.{key}: must be bool. Found: {value!r} ({type(value)})') | ||
|
|
||
| illegal = _INJECTED_PARAMS & set(method_params) | ||
| if illegal: | ||
| errors.append( | ||
| f'method_params: must not define injected parameters {sorted(illegal)} ' | ||
| f'(resolved from credentials/instance_jobs).' | ||
| ) | ||
|
|
||
| return errors | ||
|
|
||
|
|
||
| def _validate_instance_jobs(instance_jobs): | ||
| error_message = ( | ||
| "Each job in 'instance_jobs' must be a dict with an 'output_destination' (string), " | ||
| "'synthesizers' (list of strings), and 'datasets' (list of strings or dict with " | ||
| "'include' and optional 'exclude')." | ||
| ) | ||
| invalid_jobs = [] | ||
| for job in instance_jobs: | ||
| if not isinstance(job, dict): | ||
| invalid_jobs.append(job) | ||
| continue | ||
|
|
||
| if 'datasets' not in job or 'synthesizers' not in job or 'output_destination' not in job: | ||
| invalid_jobs.append(job) | ||
| continue | ||
|
|
||
| synthesizers = job['synthesizers'] | ||
| if not isinstance(synthesizers, list) or not all(isinstance(s, str) for s in synthesizers): | ||
| invalid_jobs.append(job) | ||
| continue | ||
|
|
||
| output_destination = job['output_destination'] | ||
| if not isinstance(output_destination, str) or not output_destination: | ||
| invalid_jobs.append(job) | ||
| continue | ||
|
|
||
| datasets = job['datasets'] | ||
| if isinstance(datasets, list): | ||
| if not all(isinstance(d, str) for d in datasets): | ||
| invalid_jobs.append(job) | ||
| continue | ||
|
|
||
| if isinstance(datasets, dict): | ||
| include = datasets.get('include') | ||
| exclude = datasets.get('exclude') | ||
| if not isinstance(include, list) or not all(isinstance(d, str) for d in include): | ||
| invalid_jobs.append(job) | ||
| continue | ||
|
|
||
| if exclude is not None and ( | ||
| not isinstance(exclude, list) or not all(isinstance(d, str) for d in exclude) | ||
| ): | ||
| invalid_jobs.append(job) | ||
| continue | ||
|
|
||
| invalid_jobs.append(job) | ||
|
|
||
| if not invalid_jobs: | ||
| return [] | ||
|
|
||
| invalid_jobs_str = '\n'.join(str(job) for job in invalid_jobs) | ||
|
|
||
| return [f'{error_message}\nInvalid jobs:\n{invalid_jobs_str}'] | ||
|
|
||
|
|
||
| def _validate_resolved_credentials(credentials): | ||
| errors = [] | ||
| aws = credentials.get('aws', {}) | ||
| if not isinstance(aws, dict): | ||
| errors.append("credentials['aws'] must be a dict.") | ||
| else: | ||
| if any(aws.values()): | ||
| for key in _AWS_CREDENTIAL_KEYS: | ||
| key = key.lower() | ||
| if aws.get(key) in (None, ''): | ||
| errors.append(f"credentials['aws']['{key}'] is missing or empty.") | ||
|
|
||
| sdv = credentials.get('sdv_enterprise', {}) | ||
| if not isinstance(sdv, dict): | ||
| errors.append("credentials['sdv_enterprise'] must be a dict.") | ||
| else: | ||
| username = sdv.get('sdv_enterprise_username') | ||
| license_key = sdv.get('sdv_enterprise_license_key') | ||
| message = ( | ||
| "credentials['sdv_enterprise'] require both 'sdv_enterprise_username' and " | ||
| "'sdv_enterprise_license_key' to be provided and non-empty if any SDV Enterprise" | ||
| ' credential is provided.' | ||
| ) | ||
| if bool(username) != bool(license_key): | ||
| errors.append(message) | ||
|
|
||
| gcp = credentials.get('gcp', {}) | ||
| if not isinstance(gcp, dict): | ||
| errors.append("credentials['gcp'] must be a dict.") | ||
| else: | ||
| if gcp: | ||
| for key in _GCP_SERVICE_ACCOUNT_REQUIRED_KEYS: | ||
| if gcp.get(key) in (None, ''): | ||
| errors.append(f"credentials['gcp']['{key}'] is missing or empty.") | ||
|
|
||
| return sorted(errors) | ||
|
|
||
|
|
||
| def _validate_credentials(credentials_filepath): | ||
| if credentials_filepath is not None and not isinstance(credentials_filepath, str): | ||
| return ['credentials_filepath: must be a string path to the credentials file or None.'] | ||
|
|
||
| credentials = resolve_credentials(credentials_filepath) | ||
| return _validate_resolved_credentials(credentials) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,10 @@ | ||||
| method_params: | ||||
| timeout: 345600 | ||||
| compute_quality_score: true | ||||
| compute_diagnostic_score: true | ||||
| compute_privacy_score: false | ||||
|
|
||||
| compute: | ||||
| service: 'gcp' | ||||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this PR, we only indicate which compute service to use. In a future issue, we will move the compute config defined here SDGym/sdgym/_benchmark/config_utils.py Line 19 in 3c2a248
Inside this yaml file also |
||||
|
|
||||
| credentials_filepath: null | ||||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: Revert before merging