hirundo 0.3.2__tar.gz → 0.3.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.
- {hirundo-0.3.2 → hirundo-0.3.3}/PKG-INFO +1 -1
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/__init__.py +3 -1
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/dataset_qa.py +22 -5
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/external_eval.py +9 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/llm_behavior_eval.py +29 -1
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/unlearning_llm.py +18 -9
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo.egg-info/PKG-INFO +1 -1
- {hirundo-0.3.2 → hirundo-0.3.3}/pyproject.toml +2 -2
- {hirundo-0.3.2 → hirundo-0.3.3}/tests/test_external_eval.py +60 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/tests/test_llm_behavior_eval.py +18 -1
- {hirundo-0.3.2 → hirundo-0.3.3}/LICENSE +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/README.md +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/__main__.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_column_options.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_constraints.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_dataframe.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_env.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_headers.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_hirundo_error.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_http.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_iter_sse_retrying.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_llm_pipeline.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_llm_sources.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_run_checking.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_run_status.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_sse_event_data.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_timeouts.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/_urls.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/cli.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/dataset_enum.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/dataset_qa_results.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/git.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/labeling.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/llm_behavior_eval_results.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/llm_bias_type.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/logger.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/storage.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo/unzip.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo.egg-info/SOURCES.txt +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo.egg-info/dependency_links.txt +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo.egg-info/entry_points.txt +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo.egg-info/requires.txt +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/hirundo.egg-info/top_level.txt +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/setup.cfg +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/tests/test_llm_behavior_eval_presets.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/tests/test_unzip.py +0 -0
- {hirundo-0.3.2 → hirundo-0.3.3}/tests/testing_utils.py +0 -0
|
@@ -67,6 +67,7 @@ from .storage import (
|
|
|
67
67
|
StorageS3,
|
|
68
68
|
)
|
|
69
69
|
from .unlearning_llm import (
|
|
70
|
+
Aggressiveness,
|
|
70
71
|
BiasBehavior,
|
|
71
72
|
CustomBehavior,
|
|
72
73
|
HallucinationBehavior,
|
|
@@ -131,6 +132,7 @@ __all__ = [
|
|
|
131
132
|
"StorageGit",
|
|
132
133
|
"StorageConfig",
|
|
133
134
|
"DatasetQAResults",
|
|
135
|
+
"Aggressiveness",
|
|
134
136
|
"BiasBehavior",
|
|
135
137
|
"CustomBehavior",
|
|
136
138
|
"HallucinationBehavior",
|
|
@@ -152,4 +154,4 @@ __all__ = [
|
|
|
152
154
|
]
|
|
153
155
|
|
|
154
156
|
# Keep this literal in sync with pyproject.toml; release workflows read it.
|
|
155
|
-
__version__ = "0.3.
|
|
157
|
+
__version__ = "0.3.3"
|
|
@@ -326,7 +326,7 @@ class QADataset(BaseModel):
|
|
|
326
326
|
if self.storage_config == StorageTypes.LOCAL:
|
|
327
327
|
return False
|
|
328
328
|
if (
|
|
329
|
-
isinstance(self.storage_config,
|
|
329
|
+
isinstance(self.storage_config, StorageConfig | ResponseStorageConfig)
|
|
330
330
|
and self.storage_config.type == StorageTypes.LOCAL
|
|
331
331
|
):
|
|
332
332
|
return False
|
|
@@ -608,13 +608,26 @@ class QADataset(BaseModel):
|
|
|
608
608
|
|
|
609
609
|
Args:
|
|
610
610
|
dataset_id: The ID of the dataset to run QA on.
|
|
611
|
+
organization_id: The organization ID to use for this run. When set,
|
|
612
|
+
it overrides the default organization selection.
|
|
613
|
+
run_args: Optional QA run arguments. When omitted, the SDK loads
|
|
614
|
+
the dataset type and sends default classification arguments for
|
|
615
|
+
non-speech datasets, but omits `run_args` for speech-to-text
|
|
616
|
+
datasets. When supplied, the SDK serializes them into the
|
|
617
|
+
payload. Speech-to-text runs must not supply run arguments.
|
|
611
618
|
|
|
612
619
|
Returns:
|
|
613
620
|
ID of the run (`run_id`).
|
|
614
621
|
"""
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
622
|
+
dataset = QADataset.get_by_id(dataset_id)
|
|
623
|
+
if run_args is None:
|
|
624
|
+
if dataset.labeling_type != LabelingType.SPEECH_TO_TEXT:
|
|
625
|
+
run_args = ClassificationRunArgs()
|
|
626
|
+
else:
|
|
627
|
+
dataset._validate_run_args(run_args)
|
|
628
|
+
run_info: dict[str, typing.Any] = {}
|
|
629
|
+
if run_args is not None:
|
|
630
|
+
run_info["run_args"] = run_args.model_dump(mode="json")
|
|
618
631
|
if organization_id is not None:
|
|
619
632
|
run_info["organization_id"] = organization_id
|
|
620
633
|
run_response = requests.post(
|
|
@@ -661,7 +674,9 @@ class QADataset(BaseModel):
|
|
|
661
674
|
organization_id: The ID of the organization to run the QA for.
|
|
662
675
|
replace_dataset_if_exists: If True, the dataset will be replaced if it already exists
|
|
663
676
|
(this is determined by a dataset of the same name in the same organization).
|
|
664
|
-
run_args: The run arguments to use for the QA run
|
|
677
|
+
run_args: The run arguments to use for the QA run. When omitted,
|
|
678
|
+
non-speech datasets use default classification arguments, while
|
|
679
|
+
speech-to-text datasets omit run arguments.
|
|
665
680
|
|
|
666
681
|
Returns:
|
|
667
682
|
An ID of the run (`run_id`) and stores that `run_id` on the instance
|
|
@@ -672,6 +687,8 @@ class QADataset(BaseModel):
|
|
|
672
687
|
organization_id=organization_id,
|
|
673
688
|
replace_if_exists=replace_dataset_if_exists,
|
|
674
689
|
)
|
|
690
|
+
if run_args is None and self.labeling_type != LabelingType.SPEECH_TO_TEXT:
|
|
691
|
+
run_args = ClassificationRunArgs()
|
|
675
692
|
if run_args is not None:
|
|
676
693
|
self._validate_run_args(run_args)
|
|
677
694
|
run_id = self.launch_qa_run(self.id, organization_id, run_args)
|
|
@@ -46,6 +46,15 @@ class ExternalEvalRunInfo(BaseModel):
|
|
|
46
46
|
source_run_id: str | None = None
|
|
47
47
|
task_ids: list[CanonicalTaskReference] = Field(min_length=1)
|
|
48
48
|
sample_limit: int | None = Field(default=None, gt=0)
|
|
49
|
+
max_model_len: int | None = Field(
|
|
50
|
+
default=None,
|
|
51
|
+
gt=0,
|
|
52
|
+
strict=True,
|
|
53
|
+
description=(
|
|
54
|
+
"Maximum model context length for the evaluation. "
|
|
55
|
+
"Omit or set None to use the model's context length."
|
|
56
|
+
),
|
|
57
|
+
)
|
|
49
58
|
|
|
50
59
|
@model_validator(mode="after")
|
|
51
60
|
def _validate_unique_task_ids(self) -> "ExternalEvalRunInfo":
|
|
@@ -7,7 +7,7 @@ from enum import Enum
|
|
|
7
7
|
from typing import overload
|
|
8
8
|
|
|
9
9
|
import httpx
|
|
10
|
-
from pydantic import BaseModel, ConfigDict, model_validator
|
|
10
|
+
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
11
11
|
from tqdm import tqdm
|
|
12
12
|
from tqdm.contrib.logging import logging_redirect_tqdm
|
|
13
13
|
|
|
@@ -153,6 +153,31 @@ class EvalRunRecord(BaseModel):
|
|
|
153
153
|
bias_type: BBQBiasType | UnqoverBiasType | None = None
|
|
154
154
|
task_ids: list[str] | None = None
|
|
155
155
|
sample_limit: int | None = None
|
|
156
|
+
attempt_timeout: int | None = Field(
|
|
157
|
+
default=None,
|
|
158
|
+
description=(
|
|
159
|
+
"Server-side Inspect timeout, in seconds, for each model generation "
|
|
160
|
+
"attempt. None for non-Inspect runs or runs created before this "
|
|
161
|
+
"setting was recorded."
|
|
162
|
+
),
|
|
163
|
+
)
|
|
164
|
+
max_retries: int | None = Field(
|
|
165
|
+
default=None,
|
|
166
|
+
description=(
|
|
167
|
+
"Server-side Inspect retry limit for failed model generations. "
|
|
168
|
+
"Unrelated to the SDK's stream reconnection `max_retries` argument "
|
|
169
|
+
"on `check_run_by_id`. None for non-Inspect runs or runs created "
|
|
170
|
+
"before this setting was recorded."
|
|
171
|
+
),
|
|
172
|
+
)
|
|
173
|
+
max_model_len: int | None = Field(
|
|
174
|
+
default=None,
|
|
175
|
+
description=(
|
|
176
|
+
"Maximum model context length used by the Inspect evaluation. "
|
|
177
|
+
"None when the model's context length was used, for non-Inspect "
|
|
178
|
+
"runs, or for runs created before this setting was recorded."
|
|
179
|
+
),
|
|
180
|
+
)
|
|
156
181
|
judge_model: JudgeModel | None = None
|
|
157
182
|
run_id: str
|
|
158
183
|
mlflow_run_id: str | None
|
|
@@ -218,6 +243,9 @@ class LlmBehaviorEval:
|
|
|
218
243
|
bias_type=response_payload.get("bias_type"),
|
|
219
244
|
task_ids=response_payload.get("task_ids"),
|
|
220
245
|
sample_limit=response_payload.get("sample_limit"),
|
|
246
|
+
attempt_timeout=response_payload.get("attempt_timeout"),
|
|
247
|
+
max_retries=response_payload.get("max_retries"),
|
|
248
|
+
max_model_len=response_payload.get("max_model_len"),
|
|
221
249
|
judge_model=judge_model,
|
|
222
250
|
run_id=response_payload["run_id"],
|
|
223
251
|
mlflow_run_id=response_payload.get("mlflow_run_id"),
|
|
@@ -319,6 +319,8 @@ OutputBehaviorOptions = (
|
|
|
319
319
|
| CustomBehavior
|
|
320
320
|
)
|
|
321
321
|
|
|
322
|
+
Aggressiveness = Annotated[float, Field(gt=0, le=1, multiple_of=0.001)]
|
|
323
|
+
|
|
322
324
|
|
|
323
325
|
class LlmRunInfo(BaseModel):
|
|
324
326
|
model_config = ConfigDict(protected_namespaces=("model_validate", "model_dump"))
|
|
@@ -328,10 +330,11 @@ class LlmRunInfo(BaseModel):
|
|
|
328
330
|
target_behaviors: list[TargetBehavior]
|
|
329
331
|
target_utilities: list[CustomUtility] = Field(default_factory=list)
|
|
330
332
|
advanced_options: UnlearningLlmAdvancedOptions | None = None
|
|
333
|
+
aggressiveness: Aggressiveness | None = None
|
|
331
334
|
|
|
332
335
|
@model_validator(mode="after")
|
|
333
336
|
def validate_refusal_utilities(self) -> "LlmRunInfo":
|
|
334
|
-
"""Validate
|
|
337
|
+
"""Validate run options are compatible with the selected behaviors.
|
|
335
338
|
|
|
336
339
|
Args:
|
|
337
340
|
self: The `LlmRunInfo` instance to validate.
|
|
@@ -340,8 +343,8 @@ class LlmRunInfo(BaseModel):
|
|
|
340
343
|
The validated `LlmRunInfo` instance.
|
|
341
344
|
|
|
342
345
|
Raises:
|
|
343
|
-
ValueError: If refusal behavior is combined with
|
|
344
|
-
|
|
346
|
+
ValueError: If refusal behavior is combined with an unsupported
|
|
347
|
+
option.
|
|
345
348
|
"""
|
|
346
349
|
has_refusal = any(
|
|
347
350
|
isinstance(target_behavior, RefusalBehavior)
|
|
@@ -349,6 +352,8 @@ class LlmRunInfo(BaseModel):
|
|
|
349
352
|
)
|
|
350
353
|
if has_refusal and self.target_utilities:
|
|
351
354
|
raise ValueError("Refusal behavior does not support target utilities")
|
|
355
|
+
if has_refusal and self.aggressiveness is not None:
|
|
356
|
+
raise ValueError("Refusal behavior does not support aggressiveness")
|
|
352
357
|
return self
|
|
353
358
|
|
|
354
359
|
|
|
@@ -381,6 +386,7 @@ class OutputUnlearningLlmRun(BaseModel):
|
|
|
381
386
|
target_behaviors: list[OutputBehaviorOptions]
|
|
382
387
|
target_utilities: list[CustomUtility]
|
|
383
388
|
advanced_options: UnlearningLlmAdvancedOptions | None
|
|
389
|
+
aggressiveness: float | None = None
|
|
384
390
|
run_id: str
|
|
385
391
|
mlflow_run_id: str | None
|
|
386
392
|
status: CeleryTaskState
|
|
@@ -407,13 +413,16 @@ class LlmUnlearningRun:
|
|
|
407
413
|
run_info: The `LlmRunInfo` request model to serialize.
|
|
408
414
|
|
|
409
415
|
Returns:
|
|
410
|
-
A JSON-serializable payload derived from
|
|
411
|
-
`run_info
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
416
|
+
A JSON-serializable payload derived from a freshly validated copy
|
|
417
|
+
of `run_info`. Bias targets include the backend-only `bias_type`
|
|
418
|
+
field set to `BBQBiasType.ALL.value`. Refusal targets retain their
|
|
419
|
+
validated empty `target_utilities` field for the API request
|
|
420
|
+
schema.
|
|
415
421
|
"""
|
|
416
|
-
|
|
422
|
+
validated_run_info = LlmRunInfo.model_validate(run_info.model_dump())
|
|
423
|
+
payload = validated_run_info.model_dump(mode="json")
|
|
424
|
+
if validated_run_info.aggressiveness is None:
|
|
425
|
+
payload.pop("aggressiveness")
|
|
417
426
|
for target_behavior in payload["target_behaviors"]:
|
|
418
427
|
if target_behavior["type"] == "BIAS":
|
|
419
428
|
target_behavior["bias_type"] = BBQBiasType.ALL.value
|
|
@@ -7,7 +7,7 @@ packages = ["hirundo"]
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "hirundo"
|
|
10
|
-
version = "0.3.
|
|
10
|
+
version = "0.3.3"
|
|
11
11
|
description = "The Hirundo platform provides APIs for: LLM behavior unlearning & dataset QA."
|
|
12
12
|
authors = [{ name = "Hirundo", email = "dev@hirundo.io" }]
|
|
13
13
|
readme = "README.md"
|
|
@@ -121,7 +121,7 @@ docs = [
|
|
|
121
121
|
]
|
|
122
122
|
|
|
123
123
|
[tool.bumpver]
|
|
124
|
-
current_version = "0.3.
|
|
124
|
+
current_version = "0.3.3"
|
|
125
125
|
version_pattern = "MAJOR.MINOR.PATCH[.PYTAGNUM]"
|
|
126
126
|
|
|
127
127
|
[tool.bumpver.file_patterns]
|
|
@@ -30,8 +30,10 @@ class _Response:
|
|
|
30
30
|
return None
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
@pytest.mark.parametrize("max_model_len", [None, 32768])
|
|
33
34
|
def test_launch_external_eval_run_serializes_request(
|
|
34
35
|
monkeypatch: pytest.MonkeyPatch,
|
|
36
|
+
max_model_len: int | None,
|
|
35
37
|
) -> None:
|
|
36
38
|
captured_request: dict[str, Any] = {}
|
|
37
39
|
|
|
@@ -49,6 +51,7 @@ def test_launch_external_eval_run_serializes_request(
|
|
|
49
51
|
name="Inspect AIME",
|
|
50
52
|
source_run_id="unlearning-run-id",
|
|
51
53
|
task_ids=["inspect_evals/aime25"],
|
|
54
|
+
max_model_len=max_model_len,
|
|
52
55
|
),
|
|
53
56
|
)
|
|
54
57
|
|
|
@@ -59,9 +62,66 @@ def test_launch_external_eval_run_serializes_request(
|
|
|
59
62
|
"name": "Inspect AIME",
|
|
60
63
|
"source_run_id": "unlearning-run-id",
|
|
61
64
|
"task_ids": ["inspect_evals/aime25"],
|
|
65
|
+
**({"max_model_len": max_model_len} if max_model_len is not None else {}),
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
|
|
69
|
+
def test_launch_model_external_eval_run_serializes_context_cap(
|
|
70
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
71
|
+
) -> None:
|
|
72
|
+
captured_request: dict[str, Any] = {}
|
|
73
|
+
|
|
74
|
+
def fake_post(*args: Any, **kwargs: Any) -> _Response:
|
|
75
|
+
captured_request["url"] = args[0]
|
|
76
|
+
captured_request["json"] = kwargs["json"]
|
|
77
|
+
return _Response({"message": "Run launched", "run_id": "inspect-run-id"})
|
|
78
|
+
|
|
79
|
+
monkeypatch.setattr("hirundo.external_eval.get_headers", lambda: {})
|
|
80
|
+
monkeypatch.setattr("hirundo.external_eval.requests.post", fake_post)
|
|
81
|
+
|
|
82
|
+
ExternalEval.launch_eval_run(
|
|
83
|
+
ModelOrRun.MODEL,
|
|
84
|
+
ExternalEvalRunInfo(
|
|
85
|
+
model_id=123,
|
|
86
|
+
task_ids=["inspect_evals/aime25"],
|
|
87
|
+
max_model_len=4096,
|
|
88
|
+
),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
assert captured_request["url"].endswith("/external-evals/run/model")
|
|
92
|
+
assert captured_request["json"] == {
|
|
93
|
+
"model_id": 123,
|
|
94
|
+
"task_ids": ["inspect_evals/aime25"],
|
|
95
|
+
"max_model_len": 4096,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@pytest.mark.parametrize("max_model_len", [0, -1, 1.5, 1.0, True, "4096"])
|
|
100
|
+
def test_external_eval_run_info_rejects_invalid_context_cap(
|
|
101
|
+
max_model_len: int | float | bool | str,
|
|
102
|
+
) -> None:
|
|
103
|
+
with pytest.raises(ValidationError):
|
|
104
|
+
ExternalEvalRunInfo.model_validate(
|
|
105
|
+
{
|
|
106
|
+
"model_id": 123,
|
|
107
|
+
"task_ids": ["inspect_evals/aime25"],
|
|
108
|
+
"max_model_len": max_model_len,
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_external_eval_run_info_rejects_server_owned_settings() -> None:
|
|
114
|
+
with pytest.raises(ValidationError, match="Extra inputs are not permitted"):
|
|
115
|
+
ExternalEvalRunInfo.model_validate(
|
|
116
|
+
{
|
|
117
|
+
"model_id": 123,
|
|
118
|
+
"task_ids": ["inspect_evals/aime25"],
|
|
119
|
+
"attempt_timeout": 60,
|
|
120
|
+
"max_retries": 0,
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
|
|
65
125
|
def test_get_external_eval_catalog(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
66
126
|
def fake_get(*args: Any, **kwargs: Any) -> _Response:
|
|
67
127
|
assert args[0].endswith("/external-evals/catalog")
|
|
@@ -68,7 +68,17 @@ def test_launch_eval_run_omits_removed_custom_dataset_path(
|
|
|
68
68
|
assert "file_path" not in captured_request["json"]
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
@pytest.mark.parametrize(
|
|
72
|
+
"generation_settings",
|
|
73
|
+
[
|
|
74
|
+
{"attempt_timeout": 3600, "max_retries": 0, "max_model_len": 32768},
|
|
75
|
+
{"attempt_timeout": None, "max_retries": None, "max_model_len": None},
|
|
76
|
+
{},
|
|
77
|
+
],
|
|
78
|
+
)
|
|
79
|
+
def test_parse_inspect_evaluation_run(
|
|
80
|
+
generation_settings: dict[str, int | None],
|
|
81
|
+
) -> None:
|
|
72
82
|
run_record = LlmBehaviorEval._parse_eval_run_record(
|
|
73
83
|
{
|
|
74
84
|
"id": 1,
|
|
@@ -82,6 +92,7 @@ def test_parse_inspect_evaluation_run() -> None:
|
|
|
82
92
|
"bias_type": None,
|
|
83
93
|
"task_ids": ["inspect_evals/aime25"],
|
|
84
94
|
"sample_limit": None,
|
|
95
|
+
**generation_settings,
|
|
85
96
|
"judge_model": None,
|
|
86
97
|
"run_id": "eval-run-id",
|
|
87
98
|
"mlflow_run_id": None,
|
|
@@ -106,6 +117,9 @@ def test_parse_inspect_evaluation_run() -> None:
|
|
|
106
117
|
assert run_record.framework is EvalFramework.INSPECT_EVALS
|
|
107
118
|
assert run_record.task_ids == ["inspect_evals/aime25"]
|
|
108
119
|
assert run_record.sample_limit is None
|
|
120
|
+
assert run_record.attempt_timeout == generation_settings.get("attempt_timeout")
|
|
121
|
+
assert run_record.max_retries == generation_settings.get("max_retries")
|
|
122
|
+
assert run_record.max_model_len == generation_settings.get("max_model_len")
|
|
109
123
|
assert run_record.metrics == LlmEvalMetrics(
|
|
110
124
|
rows=[
|
|
111
125
|
LlmEvalMetricRow(
|
|
@@ -141,6 +155,9 @@ def test_parse_legacy_evaluation_run_defaults_framework() -> None:
|
|
|
141
155
|
)
|
|
142
156
|
|
|
143
157
|
assert run_record.framework is EvalFramework.LLM_BEHAVIOR_EVAL
|
|
158
|
+
assert run_record.attempt_timeout is None
|
|
159
|
+
assert run_record.max_retries is None
|
|
160
|
+
assert run_record.max_model_len is None
|
|
144
161
|
|
|
145
162
|
|
|
146
163
|
def test_parse_legacy_evaluation_run_defaults_null_framework() -> None:
|
|
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
|