Video-ORA-4B / code /orarl /evaluation /manifest.py
lyhisme's picture
Add 4B model card, benchmark assets, and release code
0185029 verified
Raw
History Blame Contribute Delete
20.1 kB
"""Validation and loading for the canonical ``datasets.jsonl`` manifest."""
from __future__ import annotations
import json
import re
from collections.abc import Iterable, Mapping
from pathlib import Path
from typing import Any, TypedDict, Union
from urllib.parse import urlsplit
from .layout import (
MANIFEST_FILENAME,
LayoutError,
artifact_directory,
media_directory,
path_is_within,
validate_annotation_path,
validate_artifact_path,
validate_dataset_id,
validate_media_path,
validate_repository_assets,
validate_repository_path,
validate_sha256,
validate_unique_paths,
)
from .schema import (
EVALUATION_SCHEMA_VERSION,
EvaluationSchemaError,
declared_repository_paths,
evaluation_asset_paths,
load_evaluation_jsonl,
)
_ENVIRONMENT_NAME_RE = re.compile(r"^[A-Z][A-Z0-9_]*$")
_PATH_ENV_SUFFIXES = (
"_FILE",
"_DIR",
"_ROOT",
"_PATH",
"_CKPT",
"_CFG",
"_BASE",
"_PREFIX",
)
class _RequiredDatasetManifestRecord(TypedDict):
schema_version: int
benchmark: str
split: str
task: str
annotation_path: str
media_paths: list[str]
artifact_paths: list[str]
expected_count: int
license: str
source_url: str
redistribution_authorized: bool
evaluation: dict[str, Any]
class DatasetManifestRecord(_RequiredDatasetManifestRecord, total=False):
"""One canonical manifest record for a benchmark/split pair."""
family: str
preprocessing: dict[str, Any]
legacy_environment: dict[str, Any]
checksums: dict[str, str]
metadata: dict[str, Any]
class ManifestError(ValueError):
"""Raised when ``datasets.jsonl`` or its referenced repository is invalid."""
def _append_layout_error(errors: list[str], callback: Any) -> None:
try:
callback()
except LayoutError as error:
errors.append(str(error))
def _valid_source_url(value: object) -> bool:
if not isinstance(value, str) or not value or value != value.strip():
return False
if any(character.isspace() for character in value):
return False
parsed = urlsplit(value)
return (
parsed.scheme in {"http", "https"}
and bool(parsed.netloc)
and parsed.username is None
and parsed.password is None
)
def _string_paths(
value: Any,
field: str,
errors: list[str],
) -> list[str]:
if not isinstance(value, list):
errors.append(f"{field} must be a list")
return []
paths: list[str] = []
for index, path in enumerate(value):
if not isinstance(path, str):
errors.append(f"{field}[{index}] must be a repository path string")
else:
paths.append(path)
return paths
def _manifest_checksums(record: Mapping[str, Any], errors: list[str]) -> dict[str, str]:
raw_checksums = record.get("checksums")
if raw_checksums is None:
return {}
if not isinstance(raw_checksums, Mapping):
errors.append("checksums must be a JSON object when provided")
return {}
checksums: dict[str, str] = {}
for raw_path, raw_digest in raw_checksums.items():
if not isinstance(raw_path, str):
errors.append("checksum keys must be repository path strings")
continue
try:
path = validate_repository_path(raw_path, context="checksum path")
digest = validate_sha256(raw_digest, context=f"checksum for {path}")
except LayoutError as error:
errors.append(str(error))
continue
checksums[path] = digest
_append_layout_error(
errors,
lambda: validate_unique_paths(checksums, context="checksum paths"),
)
return checksums
def dataset_manifest_record_errors(record: Any) -> list[str]:
"""Collect schema and canonical-layout errors for one manifest record."""
if not isinstance(record, Mapping):
return ["record must be a JSON object"]
errors: list[str] = []
version = record.get("schema_version")
if isinstance(version, bool) or version != EVALUATION_SCHEMA_VERSION:
errors.append(f"schema_version must be {EVALUATION_SCHEMA_VERSION}")
for field in ("benchmark", "split", "task"):
value = record.get(field)
_append_layout_error(
errors,
lambda value=value, field=field: validate_dataset_id(value, context=field),
)
family = record.get("family")
if family is not None:
_append_layout_error(
errors,
lambda: validate_dataset_id(family, context="family"),
)
benchmark = record.get("benchmark")
split = record.get("split")
if isinstance(benchmark, str) and isinstance(split, str):
_append_layout_error(
errors,
lambda: validate_annotation_path(
record.get("annotation_path"),
benchmark,
split,
),
)
elif "annotation_path" not in record:
errors.append("annotation_path is required")
media_paths = _string_paths(record.get("media_paths"), "media_paths", errors)
artifact_paths = _string_paths(record.get("artifact_paths"), "artifact_paths", errors)
if isinstance(benchmark, str):
for index, path in enumerate(media_paths):
_append_layout_error(
errors,
lambda path=path, index=index: validate_media_path(
path,
benchmark,
allow_directory=True,
context=f"media_paths[{index}]",
),
)
for index, path in enumerate(artifact_paths):
_append_layout_error(
errors,
lambda path=path, index=index: validate_artifact_path(
path,
benchmark,
allow_directory=True,
context=f"artifact_paths[{index}]",
),
)
_append_layout_error(
errors,
lambda: validate_unique_paths(media_paths, context="media_paths"),
)
_append_layout_error(
errors,
lambda: validate_unique_paths(artifact_paths, context="artifact_paths"),
)
expected_count = record.get("expected_count")
if (
isinstance(expected_count, bool)
or not isinstance(expected_count, int)
or expected_count < 0
):
errors.append("expected_count must be a nonnegative integer")
license_name = record.get("license")
if not isinstance(license_name, str) or not license_name.strip():
errors.append("license must be a nonempty string")
if not _valid_source_url(record.get("source_url")):
errors.append("source_url must be an HTTP(S) URL without embedded credentials")
if not isinstance(record.get("redistribution_authorized"), bool):
errors.append("redistribution_authorized must be an explicit boolean")
evaluation = record.get("evaluation")
if not isinstance(evaluation, Mapping) or not evaluation:
errors.append("evaluation must be a nonempty JSON object")
for field in ("preprocessing", "metadata"):
value = record.get(field)
if value is not None and not isinstance(value, Mapping):
errors.append(f"{field} must be a JSON object when provided")
legacy = record.get("legacy_environment")
legacy_paths: list[str] = []
if legacy is not None:
if not isinstance(legacy, Mapping):
errors.append("legacy_environment must be a JSON object when provided")
else:
for name, value in legacy.items():
if not isinstance(name, str) or not _ENVIRONMENT_NAME_RE.fullmatch(name):
errors.append(
"legacy_environment names must use uppercase letters, digits, "
"and underscores"
)
if isinstance(value, (Mapping, tuple, set)) or value is None:
errors.append(
f"legacy_environment[{name!r}] must be a JSON scalar or list"
)
continue
if isinstance(value, list) and not all(
isinstance(item, (str, int, float, bool)) for item in value
):
errors.append(
f"legacy_environment[{name!r}] lists must contain only JSON scalars"
)
continue
if isinstance(name, str) and name.endswith(_PATH_ENV_SUFFIXES):
if not isinstance(value, str):
errors.append(
f"legacy_environment[{name!r}] must be a path string"
)
continue
legacy_paths.append(value)
_append_layout_error(
errors,
lambda value=value, name=name: validate_repository_path(
value,
context=f"legacy_environment[{name!r}]",
),
)
profile_paths: list[str] = []
for field in ("preprocessing", "evaluation", "metadata"):
value = record.get(field)
if isinstance(value, Mapping):
try:
declared = declared_repository_paths(value, context=field)
except LayoutError as error:
errors.append(str(error))
continue
for context, path in declared:
profile_paths.append(path)
_append_layout_error(
errors,
lambda path=path, context=context: validate_repository_path(
path,
context=context,
),
)
checksums = _manifest_checksums(record, errors)
declared_paths = []
annotation = record.get("annotation_path")
if isinstance(annotation, str):
declared_paths.append(annotation)
declared_paths.extend(media_paths)
declared_paths.extend(artifact_paths)
declared_paths.extend(legacy_paths)
declared_paths.extend(profile_paths)
declared_paths.extend(checksums)
_append_layout_error(
errors,
lambda: validate_unique_paths(
declared_paths,
context="manifest paths",
allow_exact_duplicates=True,
),
)
try:
json.dumps(record, ensure_ascii=False, allow_nan=False)
except (TypeError, ValueError) as error:
errors.append(f"record must contain only finite JSON values: {error}")
return errors
def validate_dataset_manifest_record(
record: Any,
*,
context: str = "manifest record",
) -> Mapping[str, Any]:
"""Validate one ``datasets.jsonl`` record and return it unchanged."""
errors = dataset_manifest_record_errors(record)
if errors:
raise ManifestError(f"{context}: " + "; ".join(errors))
return record
def _record_paths(record: Mapping[str, Any]) -> tuple[list[str], list[str]]:
paths = [str(record["annotation_path"])]
paths.extend(str(path) for path in record["media_paths"])
paths.extend(str(path) for path in record["artifact_paths"])
legacy = record.get("legacy_environment")
if isinstance(legacy, Mapping):
paths.extend(
str(value)
for name, value in legacy.items()
if isinstance(name, str)
and name.endswith(_PATH_ENV_SUFFIXES)
and isinstance(value, str)
)
for field in ("preprocessing", "evaluation", "metadata"):
payload = record.get(field)
if isinstance(payload, Mapping):
paths.extend(path for _context, path in declared_repository_paths(payload))
files = [str(record["annotation_path"])]
checksums = record.get("checksums")
if isinstance(checksums, Mapping):
files.extend(str(path) for path in checksums)
return paths, files
def validate_dataset_manifest(
records: Iterable[Any],
*,
repository_root: Union[str, Path, None] = None,
checksums: Mapping[str, str] | None = None,
context: str = MANIFEST_FILENAME,
) -> list[Mapping[str, Any]]:
"""Validate manifest records, dataset uniqueness, paths, and optional assets."""
validated: list[Mapping[str, Any]] = []
datasets: dict[tuple[str, str], int] = {}
path_spellings: dict[str, str] = {}
asset_paths: list[str] = []
file_paths: list[str] = []
merged_checksums: dict[str, str] = {}
for index, record in enumerate(records, start=1):
row_context = f"{context}:{index}"
validated_record = validate_dataset_manifest_record(record, context=row_context)
key = (
str(validated_record["benchmark"]),
str(validated_record["split"]),
)
previous = datasets.get(key)
if previous is not None:
raise ManifestError(
f"{row_context}: duplicate dataset {key[0]}/{key[1]} "
f"(first seen at row {previous})"
)
datasets[key] = index
paths, files = _record_paths(validated_record)
for path in paths:
folded = path.casefold()
previous_path = path_spellings.get(folded)
if previous_path is not None and previous_path != path:
raise ManifestError(
f"{row_context}: manifest path case collision: "
f"{previous_path!r} and {path!r}"
)
path_spellings[folded] = path
asset_paths.extend(paths)
file_paths.extend(files)
record_checksums = validated_record.get("checksums")
if isinstance(record_checksums, Mapping):
for path, digest in record_checksums.items():
previous_digest = merged_checksums.get(str(path))
if previous_digest is not None and previous_digest != digest:
raise ManifestError(f"{row_context}: conflicting checksums for {path}")
merged_checksums[str(path)] = str(digest)
validated.append(validated_record)
for raw_path, raw_digest in (checksums or {}).items():
try:
path = validate_repository_path(raw_path, context="checksum path")
digest = validate_sha256(raw_digest, context=f"checksum for {path}")
except LayoutError as error:
raise ManifestError(f"{context}: {error}") from error
previous_digest = merged_checksums.get(path)
if previous_digest is not None and previous_digest != digest:
raise ManifestError(f"{context}: conflicting checksums for {path}")
merged_checksums[path] = digest
if checksums is not None and repository_root is None:
raise ManifestError(f"{context}: repository_root is required for checksums")
if repository_root is not None:
try:
validate_repository_assets(
asset_paths,
repository_root,
checksums=merged_checksums,
file_paths=file_paths,
context=f"{context} assets",
)
except LayoutError as error:
raise ManifestError(str(error)) from error
return validated
def _manifest_path(path: Union[str, Path]) -> Path:
candidate = Path(path)
if candidate.is_dir():
candidate = candidate / MANIFEST_FILENAME
if candidate.name != MANIFEST_FILENAME:
raise ManifestError(f"evaluation manifest must be named {MANIFEST_FILENAME}")
return candidate
def load_dataset_manifest(
path: Union[str, Path],
*,
repository_root: Union[str, Path, None] = None,
checksums: Mapping[str, str] | None = None,
) -> list[Mapping[str, Any]]:
"""Load and validate ``datasets.jsonl`` from a file or repository root."""
input_path = _manifest_path(path)
records: list[Any] = []
with input_path.open("r", encoding="utf-8") as handle:
for line_number, line in enumerate(handle, start=1):
if not line.strip():
continue
try:
record = json.loads(line)
except json.JSONDecodeError as error:
raise ManifestError(
f"{input_path}:{line_number}: invalid JSON: {error}"
) from error
records.append(record)
return validate_dataset_manifest(
records,
repository_root=repository_root,
checksums=checksums,
context=str(input_path),
)
def _path_is_declared(path: str, declarations: Iterable[str]) -> bool:
return any(path_is_within(path, declaration) for declaration in declarations)
def validate_evaluation_repository(
repository_root: Union[str, Path],
*,
checksums: Mapping[str, str] | None = None,
require_redistribution_authorized: bool = True,
) -> dict[tuple[str, str], list[Mapping[str, Any]]]:
"""Validate a staged repository, its manifests, row counts, and all assets."""
root = Path(repository_root)
manifest = load_dataset_manifest(
root,
repository_root=root,
checksums=checksums,
)
datasets: dict[tuple[str, str], list[Mapping[str, Any]]] = {}
path_spellings: dict[str, str] = {}
for index, dataset in enumerate(manifest, start=1):
benchmark = str(dataset["benchmark"])
split = str(dataset["split"])
task = str(dataset["task"])
if require_redistribution_authorized and not dataset["redistribution_authorized"]:
raise ManifestError(
f"{MANIFEST_FILENAME}:{index}: redistribution is not authorized for "
f"{benchmark}/{split}"
)
annotation = root.joinpath(str(dataset["annotation_path"]))
try:
rows = load_evaluation_jsonl(
annotation,
benchmark=benchmark,
split=split,
eval_task=task,
repository_root=root,
)
except EvaluationSchemaError as error:
raise ManifestError(str(error)) from error
expected_count = int(dataset["expected_count"])
if len(rows) != expected_count:
raise ManifestError(
f"{benchmark}/{split}: expected {expected_count} rows, found {len(rows)}"
)
media_paths = [str(path) for path in dataset["media_paths"]]
artifact_paths = [str(path) for path in dataset["artifact_paths"]]
media_root = f"{media_directory(benchmark)}/"
artifact_root = f"{artifact_directory(benchmark)}/"
for row_number, row in enumerate(rows, start=1):
for path in evaluation_asset_paths(row):
if path.startswith(media_root):
declarations = media_paths
elif path.startswith(artifact_root):
declarations = artifact_paths
else:
declarations = []
if declarations and not _path_is_declared(path, declarations):
raise ManifestError(
f"{benchmark}/{split}:{row_number}: asset {path!r} is not covered "
"by the dataset manifest"
)
if not declarations and path.startswith(("media/", "artifacts/")):
raise ManifestError(
f"{benchmark}/{split}:{row_number}: asset {path!r} has no declared root"
)
folded = path.casefold()
previous = path_spellings.get(folded)
if previous is not None and previous != path:
raise ManifestError(
f"{benchmark}/{split}:{row_number}: asset path case collision: "
f"{previous!r} and {path!r}"
)
path_spellings[folded] = path
datasets[(benchmark, split)] = rows
return datasets