Video-ORA-9B / code /tests /test_evaluation_schema.py
lyhisme's picture
Add OraRL training and evaluation code
53c10a4 verified
Raw
History Blame Contribute Delete
7.98 kB
from __future__ import annotations
import hashlib
import sys
import tempfile
import unittest
from copy import deepcopy
from pathlib import Path
ORARL_ROOT = Path(__file__).resolve().parents[1]
if str(ORARL_ROOT) not in sys.path:
sys.path.insert(0, str(ORARL_ROOT))
from orarl.evaluation import ( # noqa: E402
EVALUATION_SCHEMA_VERSION,
EvaluationSchemaError,
annotation_path,
artifact_directory,
media_directory,
validate_dataset_id,
validate_evaluation_row,
validate_evaluation_rows,
validate_repository_path,
)
def _row(
sample_id: str = "sample-001",
video: str = "media/video_qa/videomme/videos/clip.mp4",
):
return {
"schema_version": EVALUATION_SCHEMA_VERSION,
"eval_task": "videomme",
"sample_id": sample_id,
"benchmark": "videomme",
"split": "test",
"problem": "What happens next?",
"answer": "B",
"images": [],
"videos": [video],
"problem_type": "video_qa_mc",
"source": "Video-MME",
"family": "video_qa",
"choices": ["A. Nothing", "B. A person enters"],
"subtitles": ["media/video_qa/videomme/subtitles/clip.srt"],
"preprocessed": {
"video_path": "artifacts/video_qa/videomme/preprocessed/clip.npz",
"settings": {"frames": 128},
},
"task_payload": {"duration": 12.5},
"metadata": {"question_id": "q-1"},
"evaluation": {"group": "short_video"},
}
class EvaluationSchemaTests(unittest.TestCase):
def test_accepts_training_core_and_eval_envelope(self) -> None:
row = _row()
self.assertIs(validate_evaluation_row(row), row)
self.assertEqual(
annotation_path("videomme", "test"),
"annotations/video_qa/videomme/test.jsonl",
)
def test_accepts_mask_backed_segmentation_without_text_answer(self) -> None:
row = _row(video="")
row.update(
{
"eval_task": "segmentation",
"benchmark": "segmentation",
"split": "mevis",
"answer": None,
"images": [],
"videos": ["media/segmentation/videos/mevis/clip.mp4"],
"problem_type": "segmentation",
"source": "mevis",
"family": "segmentation",
"task_payload": {
"segmentation_output": {
"frames": ["00000"],
"segmentation_rle": {
"00000": {"size": [2, 2], "counts": "13"}
},
}
},
}
)
row.pop("subtitles")
row.pop("preprocessed")
self.assertIs(validate_evaluation_row(row), row)
row["task_payload"] = {}
with self.assertRaisesRegex(
EvaluationSchemaError,
"answer must contain a nonempty oracle label",
):
validate_evaluation_row(row)
def test_video_qa_benchmarks_share_one_physical_family(self) -> None:
for benchmark in (
"videomme",
"videommev2",
"mvbench",
"mmvu",
"videoholmes",
"longvideobench",
"mlvu",
):
with self.subTest(benchmark=benchmark):
self.assertEqual(
annotation_path(benchmark, "test"),
f"annotations/video_qa/{benchmark}/test.jsonl",
)
self.assertEqual(
media_directory(benchmark, "videos"),
f"media/video_qa/{benchmark}/videos",
)
self.assertEqual(
artifact_directory(benchmark),
f"artifacts/video_qa/{benchmark}",
)
self.assertEqual(
annotation_path("spatial_grounding", "refcoco_val"),
"annotations/spatial_grounding/refcoco_val.jsonl",
)
def test_spatial_intelligence_benchmarks_share_one_physical_family(self) -> None:
for benchmark in ("vsi", "mmsi", "mindcube", "revsi"):
with self.subTest(benchmark=benchmark):
self.assertEqual(
annotation_path(benchmark, "test"),
f"annotations/spatial_intelligence/{benchmark}/test.jsonl",
)
self.assertEqual(
media_directory(benchmark, "videos"),
f"media/spatial_intelligence/{benchmark}/videos",
)
self.assertEqual(
artifact_directory(benchmark),
f"artifacts/spatial_intelligence/{benchmark}",
)
def test_repository_paths_are_strict_posix_relative_paths(self) -> None:
invalid = (
"/tmp/clip.mp4",
"https://example.invalid/clip.mp4",
r"media\videomme\videos\clip.mp4",
"media/videomme/videos/../clip.mp4",
"media/videomme/videos/./clip.mp4",
)
for path in invalid:
with self.subTest(path=path):
with self.assertRaises(ValueError):
validate_repository_path(path)
for path in invalid:
with self.subTest(row_path=path):
row = _row(video=path)
with self.assertRaises(EvaluationSchemaError):
validate_evaluation_row(row)
def test_requires_snake_case_dataset_identifiers_and_canonical_scope(self) -> None:
for identifier in ("VideoMME", "video-mme", "video__mme", "_videomme"):
with self.subTest(identifier=identifier):
with self.assertRaises(ValueError):
validate_dataset_id(identifier)
row = _row(video="media/other_benchmark/videos/clip.mp4")
with self.assertRaisesRegex(
EvaluationSchemaError,
"media/video_qa/videomme/videos",
):
validate_evaluation_row(row)
def test_rejects_duplicate_rows_and_asset_case_collisions(self) -> None:
with self.assertRaisesRegex(EvaluationSchemaError, "duplicate sample_id"):
validate_evaluation_rows([_row(), deepcopy(_row())])
second = _row(
sample_id="sample-002",
video="media/video_qa/videomme/videos/Clip.mp4",
)
with self.assertRaisesRegex(EvaluationSchemaError, "case collision"):
validate_evaluation_rows([_row(), second])
def test_can_verify_asset_existence_and_checksums(self) -> None:
with tempfile.TemporaryDirectory() as raw_tmp:
root = Path(raw_tmp)
assets = {
"media/video_qa/videomme/videos/clip.mp4": b"video",
"media/video_qa/videomme/subtitles/clip.srt": b"subtitle",
"artifacts/video_qa/videomme/preprocessed/clip.npz": b"artifact",
}
for relative, content in assets.items():
path = root / relative
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(content)
video_path = "media/video_qa/videomme/videos/clip.mp4"
checksum = hashlib.sha256(assets[video_path]).hexdigest()
validate_evaluation_row(
_row(),
repository_root=root,
checksums={video_path: checksum},
)
with self.assertRaisesRegex(EvaluationSchemaError, "checksum mismatch"):
validate_evaluation_row(
_row(),
repository_root=root,
checksums={video_path: "0" * 64},
)
(root / video_path).unlink()
with self.assertRaisesRegex(EvaluationSchemaError, "does not exist"):
validate_evaluation_row(_row(), repository_root=root)
if __name__ == "__main__":
unittest.main()