SafeLLM4SE 0.1.1__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.
- safellm4se/__init__.py +13 -0
- safellm4se/compare.py +57 -0
- safellm4se/comparing/__init__.py +0 -0
- safellm4se/comparing/cli.py +176 -0
- safellm4se/comparing/comparator.py +58 -0
- safellm4se/comparing/metrics.py +722 -0
- safellm4se/comparing/models.py +67 -0
- safellm4se/comparing/plots.py +335 -0
- safellm4se/comparing/writer.py +30 -0
- safellm4se/py.typed +1 -0
- safellm4se/report.py +58 -0
- safellm4se/reporting/__init__.py +13 -0
- safellm4se/reporting/cli.py +180 -0
- safellm4se/reporting/metrics.py +259 -0
- safellm4se/reporting/models.py +22 -0
- safellm4se/reporting/plots.py +368 -0
- safellm4se/reporting/reader.py +107 -0
- safellm4se/reporting/reporter.py +45 -0
- safellm4se/reporting/writer.py +30 -0
- safellm4se/sample.py +63 -0
- safellm4se/sampling/__init__.py +6 -0
- safellm4se/sampling/cli.py +448 -0
- safellm4se/sampling/config/__init__.py +5 -0
- safellm4se/sampling/config/config.py +33 -0
- safellm4se/sampling/config/logger.py +89 -0
- safellm4se/sampling/evaluators.py +312 -0
- safellm4se/sampling/locking.py +37 -0
- safellm4se/sampling/models.py +40 -0
- safellm4se/sampling/myevaluators/__init__.py +1 -0
- safellm4se/sampling/myevaluators/base_evaluator.py +119 -0
- safellm4se/sampling/myevaluators/gemini/__init__.py +0 -0
- safellm4se/sampling/myevaluators/gemini/common.py +540 -0
- safellm4se/sampling/myevaluators/gemini/humaneval_fullbench.py +226 -0
- safellm4se/sampling/myevaluators/gemini/humaneval_oneprogram.py +110 -0
- safellm4se/sampling/myevaluators/gemini/random.py +73 -0
- safellm4se/sampling/myevaluators/grok_evaluator.py +143 -0
- safellm4se/sampling/myevaluators/groq/__init__.py +1 -0
- safellm4se/sampling/myevaluators/groq/common.py +605 -0
- safellm4se/sampling/myevaluators/groq/humaneval_fullbench.py +223 -0
- safellm4se/sampling/myevaluators/groq/humaneval_oneprogram.py +108 -0
- safellm4se/sampling/myevaluators/groq/random.py +79 -0
- safellm4se/sampling/myevaluators/ollama/__init__.py +0 -0
- safellm4se/sampling/myevaluators/ollama/common.py +489 -0
- safellm4se/sampling/myevaluators/ollama/humaneval_fullbench.py +186 -0
- safellm4se/sampling/myevaluators/ollama/humaneval_oneprogram.py +108 -0
- safellm4se/sampling/myevaluators/ollama/random.py +71 -0
- safellm4se/sampling/myevaluators/random_binary_evaluator.py +81 -0
- safellm4se/sampling/myevaluators/random_normal_evaluator.py +90 -0
- safellm4se/sampling/persistence.py +477 -0
- safellm4se/sampling/sampler.py +198 -0
- safellm4se/sampling/statistics.py +35 -0
- safellm4se/statistical_utils.py +446 -0
- safellm4se-0.1.1.dist-info/METADATA +166 -0
- safellm4se-0.1.1.dist-info/RECORD +58 -0
- safellm4se-0.1.1.dist-info/WHEEL +5 -0
- safellm4se-0.1.1.dist-info/entry_points.txt +4 -0
- safellm4se-0.1.1.dist-info/licenses/LICENSE +21 -0
- safellm4se-0.1.1.dist-info/top_level.txt +1 -0
safellm4se/__init__.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Public package interface for SafeLLM4SE."""
|
|
2
|
+
|
|
3
|
+
from safellm4se.sampling.models import SamplerSettings, SamplingObservation
|
|
4
|
+
from safellm4se.sampling.sampler import AdaptiveSampler
|
|
5
|
+
|
|
6
|
+
__version__: str = "0.1.0"
|
|
7
|
+
|
|
8
|
+
__all__: list[str] = [
|
|
9
|
+
"AdaptiveSampler",
|
|
10
|
+
"SamplerSettings",
|
|
11
|
+
"SamplingObservation",
|
|
12
|
+
"__version__",
|
|
13
|
+
]
|
safellm4se/compare.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Command-line entry point for SafeLLM4SE two-sample CSV comparisons."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from loguru import logger
|
|
7
|
+
|
|
8
|
+
from safellm4se.comparing.cli import parse_args, settings_from_args
|
|
9
|
+
from safellm4se.comparing.comparator import generate_comparison_report
|
|
10
|
+
from safellm4se.comparing.models import ComparisonSettings
|
|
11
|
+
from safellm4se.sampling.config.logger import create_log_file_path, setup_logger
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _console_log_level_from_args(args: argparse.Namespace) -> str | None:
|
|
15
|
+
"""Return the console log level requested by command-line arguments.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
args: Parsed command-line arguments.
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
A log level for console output, or None when console logging is disabled.
|
|
22
|
+
"""
|
|
23
|
+
if args.log_level:
|
|
24
|
+
return args.log_level
|
|
25
|
+
if args.verbose:
|
|
26
|
+
return "INFO"
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def main() -> None:
|
|
31
|
+
"""Run the comparison report command-line entry point.
|
|
32
|
+
|
|
33
|
+
Raises:
|
|
34
|
+
Exception: Re-raises uncaught exceptions from comparison generation.
|
|
35
|
+
"""
|
|
36
|
+
args: argparse.Namespace = parse_args()
|
|
37
|
+
settings: ComparisonSettings = settings_from_args(args)
|
|
38
|
+
log_directory: Path = settings.output_path.parent
|
|
39
|
+
log_file: Path | None = setup_logger(
|
|
40
|
+
create_log_file_path(log_directory),
|
|
41
|
+
console_level=_console_log_level_from_args(args),
|
|
42
|
+
)
|
|
43
|
+
logger.info("Running SafeLLM4SE comparison report generation...")
|
|
44
|
+
if log_file is not None:
|
|
45
|
+
logger.info(f"Execution log written to {log_file}.")
|
|
46
|
+
try:
|
|
47
|
+
generate_comparison_report(settings)
|
|
48
|
+
final_message: str = f"Comparison report written in {settings.output_path}."
|
|
49
|
+
logger.info(final_message)
|
|
50
|
+
print(final_message)
|
|
51
|
+
except Exception:
|
|
52
|
+
logger.exception("SafeLLM4SE comparison report generation failed.")
|
|
53
|
+
raise
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if __name__ == "__main__":
|
|
57
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""Command-line parsing for SafeLLM4SE comparison reports."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from safellm4se.sampling.config.logger import LOG_LEVELS
|
|
7
|
+
|
|
8
|
+
from safellm4se.reporting.cli import MandatoryAwareDefaultsHelpFormatter
|
|
9
|
+
from safellm4se.comparing.models import ComparisonSettings
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
13
|
+
"""Build the command-line parser used by comparing.py.
|
|
14
|
+
|
|
15
|
+
Returns:
|
|
16
|
+
A configured argument parser for two-sample comparison reports.
|
|
17
|
+
"""
|
|
18
|
+
parser: argparse.ArgumentParser = argparse.ArgumentParser(
|
|
19
|
+
description="SafeLLM4SE two-sample CSV comparison reporting.",
|
|
20
|
+
formatter_class=MandatoryAwareDefaultsHelpFormatter,
|
|
21
|
+
)
|
|
22
|
+
parser.add_argument(
|
|
23
|
+
"--h",
|
|
24
|
+
action="help",
|
|
25
|
+
help="Show this help message and exit.",
|
|
26
|
+
)
|
|
27
|
+
parser.add_argument(
|
|
28
|
+
"--input",
|
|
29
|
+
required=True,
|
|
30
|
+
metavar="FILE_NAME",
|
|
31
|
+
help="Input CSV file generated by sample.py.",
|
|
32
|
+
)
|
|
33
|
+
parser.add_argument(
|
|
34
|
+
"--output",
|
|
35
|
+
default="comparing.csv",
|
|
36
|
+
metavar="FILE_NAME",
|
|
37
|
+
help="Output CSV comparison report file.",
|
|
38
|
+
)
|
|
39
|
+
parser.add_argument(
|
|
40
|
+
"--verbose",
|
|
41
|
+
action="store_true",
|
|
42
|
+
help="Show INFO and higher log messages on screen.",
|
|
43
|
+
)
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"--log",
|
|
46
|
+
dest="log_level",
|
|
47
|
+
choices=LOG_LEVELS,
|
|
48
|
+
type=str.upper,
|
|
49
|
+
metavar="LEVEL",
|
|
50
|
+
default=None,
|
|
51
|
+
help=(
|
|
52
|
+
"Show log messages on screen from the selected level. Accepted "
|
|
53
|
+
f"values: {', '.join(LOG_LEVELS)}."
|
|
54
|
+
),
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--task-id-1",
|
|
58
|
+
required=True,
|
|
59
|
+
metavar="TASK_ID",
|
|
60
|
+
help="First task identifier to include in the comparison report.",
|
|
61
|
+
)
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
"--task-name-1",
|
|
64
|
+
metavar="NAME",
|
|
65
|
+
default=None,
|
|
66
|
+
help="Optional first task name to display in generated plots.",
|
|
67
|
+
)
|
|
68
|
+
parser.add_argument(
|
|
69
|
+
"--task-id-2",
|
|
70
|
+
required=True,
|
|
71
|
+
metavar="TASK_ID",
|
|
72
|
+
help="Second task identifier to include in the comparison report.",
|
|
73
|
+
)
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
"--task-name-2",
|
|
76
|
+
metavar="NAME",
|
|
77
|
+
default=None,
|
|
78
|
+
help="Optional second task name to display in generated plots.",
|
|
79
|
+
)
|
|
80
|
+
parser.add_argument(
|
|
81
|
+
"--test-type",
|
|
82
|
+
required=True,
|
|
83
|
+
choices=["paired", "independent"],
|
|
84
|
+
help="Experimental design used to comparing both distributions.",
|
|
85
|
+
)
|
|
86
|
+
parser.add_argument(
|
|
87
|
+
"--confidence-level",
|
|
88
|
+
default=0.95,
|
|
89
|
+
type=float,
|
|
90
|
+
metavar="CONFIDENCE_LEVEL",
|
|
91
|
+
help="Confidence level used for confidence intervals.",
|
|
92
|
+
)
|
|
93
|
+
parser.add_argument(
|
|
94
|
+
"--boxplot",
|
|
95
|
+
metavar="FILE_NAME",
|
|
96
|
+
default=None,
|
|
97
|
+
help="Optional SVG output file for a two-sample boxplot.",
|
|
98
|
+
)
|
|
99
|
+
parser.add_argument(
|
|
100
|
+
"--violin",
|
|
101
|
+
metavar="FILE_NAME",
|
|
102
|
+
default=None,
|
|
103
|
+
help="Optional SVG output file for a two-sample violin plot.",
|
|
104
|
+
)
|
|
105
|
+
parser.add_argument(
|
|
106
|
+
"--ECDF",
|
|
107
|
+
"--ecdf",
|
|
108
|
+
dest="ecdf",
|
|
109
|
+
metavar="FILE_NAME",
|
|
110
|
+
default=None,
|
|
111
|
+
help="Optional SVG output file for a two-sample ECDF plot.",
|
|
112
|
+
)
|
|
113
|
+
parser.add_argument(
|
|
114
|
+
"--raincloud",
|
|
115
|
+
metavar="FILE_NAME",
|
|
116
|
+
default=None,
|
|
117
|
+
help="Optional SVG output file for a two-sample raincloud plot.",
|
|
118
|
+
)
|
|
119
|
+
parser.add_argument(
|
|
120
|
+
"--KDE",
|
|
121
|
+
"--kde",
|
|
122
|
+
dest="kde",
|
|
123
|
+
metavar="FILE_NAME",
|
|
124
|
+
default=None,
|
|
125
|
+
help="Optional SVG output file for a two-sample KDE plot.",
|
|
126
|
+
)
|
|
127
|
+
return parser
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def parse_args() -> argparse.Namespace:
|
|
131
|
+
"""Parse command-line arguments for a comparison report generation run.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
The parsed command-line namespace.
|
|
135
|
+
"""
|
|
136
|
+
return build_parser().parse_args()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def settings_from_args(args: argparse.Namespace) -> ComparisonSettings:
|
|
140
|
+
"""Create comparison settings from parsed command-line arguments.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
args: Parsed command-line arguments.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
Runtime settings for comparison report generation.
|
|
147
|
+
"""
|
|
148
|
+
return ComparisonSettings(
|
|
149
|
+
input_path=Path(args.input),
|
|
150
|
+
output_path=Path(args.output),
|
|
151
|
+
boxplot_path=_optional_path(args.boxplot),
|
|
152
|
+
violin_path=_optional_path(args.violin),
|
|
153
|
+
ecdf_path=_optional_path(args.ecdf),
|
|
154
|
+
raincloud_path=_optional_path(args.raincloud),
|
|
155
|
+
kde_path=_optional_path(args.kde),
|
|
156
|
+
task_id_1=args.task_id_1,
|
|
157
|
+
task_id_2=args.task_id_2,
|
|
158
|
+
task_name_1=args.task_name_1,
|
|
159
|
+
task_name_2=args.task_name_2,
|
|
160
|
+
test_type=args.test_type,
|
|
161
|
+
confidence_level=args.confidence_level,
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _optional_path(file_name: str | None) -> Path | None:
|
|
166
|
+
"""Return a Path for an optional file name.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
file_name: Optional command-line file name.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
A path when a file name was provided; otherwise, None.
|
|
173
|
+
"""
|
|
174
|
+
if file_name is None:
|
|
175
|
+
return None
|
|
176
|
+
return Path(file_name)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""High-level comparison workflow for SafeLLM4SE sampling outputs."""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from loguru import logger
|
|
6
|
+
|
|
7
|
+
from safellm4se.comparing.metrics import build_comparison_report_row
|
|
8
|
+
from safellm4se.comparing.models import ComparisonSettings
|
|
9
|
+
from safellm4se.comparing.plots import generate_requested_comparison_plots
|
|
10
|
+
from safellm4se.comparing.writer import write_comparison_report
|
|
11
|
+
from safellm4se.reporting.metrics import parse_theta_values
|
|
12
|
+
from safellm4se.reporting.reader import read_task_rows
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def generate_comparison_report(settings: ComparisonSettings) -> dict[str, Any]:
|
|
16
|
+
"""Generate a two-sample comparison report CSV.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
settings: Runtime settings for comparison report generation.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
The generated comparison report row.
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
FileNotFoundError: If the input CSV file does not exist.
|
|
26
|
+
OSError: If the output CSV file or plot files cannot be written.
|
|
27
|
+
ValueError: If the input data is invalid or inconsistent.
|
|
28
|
+
"""
|
|
29
|
+
logger.info("Reading sampling measurements from {}.", settings.input_path)
|
|
30
|
+
rows_1: list[dict[str, str]] = read_task_rows(
|
|
31
|
+
settings.input_path,
|
|
32
|
+
settings.task_id_1,
|
|
33
|
+
)
|
|
34
|
+
rows_2: list[dict[str, str]] = read_task_rows(
|
|
35
|
+
settings.input_path,
|
|
36
|
+
settings.task_id_2,
|
|
37
|
+
)
|
|
38
|
+
logger.info(
|
|
39
|
+
"Generating comparison report from {} and {} filtered rows.",
|
|
40
|
+
len(rows_1),
|
|
41
|
+
len(rows_2),
|
|
42
|
+
)
|
|
43
|
+
report_row: dict[str, Any] = build_comparison_report_row(
|
|
44
|
+
rows_1,
|
|
45
|
+
rows_2,
|
|
46
|
+
settings.test_type,
|
|
47
|
+
settings.confidence_level,
|
|
48
|
+
)
|
|
49
|
+
write_comparison_report(settings.output_path, report_row)
|
|
50
|
+
logger.info("Comparison report written to {}.", settings.output_path)
|
|
51
|
+
generated_plot_paths = generate_requested_comparison_plots(
|
|
52
|
+
parse_theta_values(rows_1),
|
|
53
|
+
parse_theta_values(rows_2),
|
|
54
|
+
settings,
|
|
55
|
+
)
|
|
56
|
+
for generated_plot_path in generated_plot_paths:
|
|
57
|
+
logger.info("Comparison plot written to {}.", generated_plot_path)
|
|
58
|
+
return report_row
|