vla / scripts /inspect_shard.py
anhtld's picture
Initial commit: DoVLA-CIL codebase (h=16 breakthrough)
adc02fa verified
Raw
History Blame Contribute Delete
5.42 kB
#!/usr/bin/env python
from __future__ import annotations
import argparse
import sys
from collections import Counter
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from dovla_cil.data.index import ShardIndex # noqa: E402
from dovla_cil.data.schema import CILRecord
from dovla_cil.data.sharding import ShardReader, group_records, iter_cil_records
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description="Inspect a CIL dataset, metadata file, or shard.")
parser.add_argument("path", type=Path)
parser.add_argument("--group-id", default=None, help="Group to display. Defaults to first group.")
parser.add_argument(
"--max-rows",
type=int,
default=32,
help="Maximum rows to print in the ranking table.",
)
args = parser.parse_args(argv)
if _looks_like_dataset(args.path):
_inspect_dataset(args.path, group_id=args.group_id, max_rows=args.max_rows)
else:
_inspect_single_shard(args.path, group_id=args.group_id, max_rows=args.max_rows)
return 0
def _inspect_dataset(path: Path, *, group_id: str | None, max_rows: int) -> None:
reader = ShardReader(path)
index = reader.index
_print_summary(index)
entries = index.load_group_index()
if not entries:
print("group_index: missing or empty")
return
selected_group_id = group_id or str(entries[0]["group_id"])
records = reader.load_group(selected_group_id)
_print_group_index_entry(_entry_by_group(entries, selected_group_id))
_print_ranking_table(records, max_rows=max_rows)
def _inspect_single_shard(path: Path, *, group_id: str | None, max_rows: int) -> None:
records = list(iter_cil_records(path))
groups = group_records(records)
candidate_counts = Counter(record.candidate_type for record in records)
print(f"shard: {path}")
print(f"num_records: {len(records)}")
print(f"num_groups: {len(groups)}")
print(f"candidate_type_counts: {dict(sorted(candidate_counts.items()))}")
if not groups:
return
selected_group_id = group_id or next(iter(groups))
if selected_group_id not in groups:
raise KeyError(f"Unknown group {selected_group_id!r} in shard {path}")
_print_ranking_table(groups[selected_group_id], max_rows=max_rows)
def _print_summary(index: ShardIndex) -> None:
metadata = index.metadata
print(f"dataset: {metadata.get('dataset_name', index.dataset_dir.name)}")
print(f"path: {index.dataset_dir}")
print(f"version: {metadata.get('version', 'unknown')}")
print(f"schema_version: {metadata.get('schema_version', 'unknown')}")
print(f"backend: {metadata.get('backend', 'unknown')}")
print(f"created_at: {metadata.get('created_at', 'unknown')}")
print(f"num_groups: {index.group_count}")
print(f"num_records: {index.record_count}")
print(f"k: {metadata.get('k', 'unknown')}")
print(f"task_count: {metadata.get('task_count', 'unknown')}")
print(f"seed: {metadata.get('seed', 'unknown')}")
print(f"shard_count: {len(index.shards)}")
print(f"group_index: {index.group_index_path}")
print(f"record_index: {index.record_index_path}")
def _print_group_index_entry(entry: dict[str, object]) -> None:
print(f"sample_group: {entry.get('group_id')}")
print(f"sample_group_task: {entry.get('task_id')}")
print(f"sample_group_shard: {entry.get('shard_path')}")
print(f"sample_group_records: {entry.get('num_records')}")
print(f"sample_group_max_reward: {entry.get('max_reward')}")
print(f"sample_group_success_count: {entry.get('success_count')}")
print(f"sample_group_candidate_type_counts: {entry.get('candidate_type_counts')}")
def _print_ranking_table(records: list[CILRecord], *, max_rows: int) -> None:
ordered = sorted(
records,
key=lambda record: (
record.rank_within_group if record.rank_within_group is not None else 10**9,
record.record_id,
),
)
print("ranking:")
print("record_id\tcandidate_type\treward.progress\tsuccess\tregret\trank\tfailure.type")
for record in ordered[:max_rows]:
print(
"\t".join(
[
record.record_id,
record.candidate_type,
f"{record.reward.progress:.6g}",
str(record.reward.terminal_success),
"" if record.regret is None else f"{record.regret:.6g}",
""
if record.rank_within_group is None
else str(record.rank_within_group),
record.failure.type if record.failure else "none",
]
)
)
if len(ordered) > max_rows:
print(f"... {len(ordered) - max_rows} more records")
def _entry_by_group(entries: list[dict[str, object]], group_id: str) -> dict[str, object]:
for entry in entries:
if entry.get("group_id") == group_id:
return entry
raise KeyError(f"Unknown group {group_id!r}")
def _looks_like_dataset(path: Path) -> bool:
if path.is_dir():
return (path / "metadata.json").exists() or (path / "manifest.json").exists()
return path.name in {"metadata.json", "manifest.json"}
if __name__ == "__main__":
raise SystemExit(main())