mmmmmcyaaa's picture
Complete shared baseline runtime dependencies
5cd1287 verified
Raw History Blame Contribute Delete
3.5 kB
#!/usr/bin/env python3
"""Validate and merge FrameSkip cache shards into one portable cache."""
from __future__ import annotations
import argparse
import json
from pathlib import Path
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--required-draws", required=True)
parser.add_argument("--shard-dir", required=True)
parser.add_argument("--shard-count", type=int, required=True)
parser.add_argument("--output", required=True)
args = parser.parse_args()
required = json.loads(Path(args.required_draws).read_text(encoding="utf-8"))
expected = {
(dataset_name, str(trajectory_id))
for dataset_name, trajectory_ids in required["datasets"].items()
for trajectory_id in trajectory_ids
}
records: dict[tuple[str, str], dict] = {}
shard_paths = []
for shard_index in range(args.shard_count):
path = Path(args.shard_dir) / f"shard_{shard_index:02d}_of_{args.shard_count:02d}.jsonl"
if not path.exists():
raise RuntimeError(f"missing FrameSkip cache shard: {path}")
shard_paths.append(path.name)
with path.open(encoding="utf-8") as source:
for line_number, line in enumerate(source, 1):
record = json.loads(line)
key = (record["dataset_name"], str(record["trajectory_id"]))
if key in records:
raise RuntimeError(f"duplicate FrameSkip cache key: {key}")
records[key] = record
if set(records) != expected:
missing = sorted(expected - set(records))[:20]
extra = sorted(set(records) - expected)[:20]
raise RuntimeError(f"cache coverage mismatch: missing={missing}, extra={extra}")
payload = {
"schema_version": 1,
"method": "FrameSkip-adapted (Gaussian-TPI fallback)",
"upstream_commit": "965becf63e9cd5cc339fbf7fde40d1db47efa67a",
"retention_ratio": 0.2,
"importance": {
"calculator": "GripperAwareImportanceCalculator",
"avi_weight": 0.6,
"vac_weight": 0.2,
"tpi_weight": 0.2,
"vac_enabled": True,
"max_vac_frames": 16,
"visual_encoder": "vit_small_patch14_dinov2.lvd142m",
"tpi": "Gaussian sigma_squared=0.2 fallback",
"gripper_boost": 2.0,
},
"pruning": {
"first_last": True,
"gripper_transition_threshold": 0.1,
"top_action_change_percentile": 90,
"min_frames_per_trajectory": 5,
"mapping": "numpy.searchsorted to the next retained index, clipped at end",
},
"schedule": {"pruned_minibatches": 5, "full_minibatches": 1},
"records": [
records[key]
for key in sorted(records, key=lambda item: (item[0], item[1]))
],
"source_shards": shard_paths,
}
output = Path(args.output)
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(payload, separators=(",", ":")) + "\n", encoding="utf-8")
print(json.dumps({
"output": str(output),
"records": len(payload["records"]),
"actual_ratio_min": min(r["actual_ratio"] for r in payload["records"]),
"actual_ratio_max": max(r["actual_ratio"] for r in payload["records"]),
"actual_ratio_mean": sum(r["actual_ratio"] for r in payload["records"]) / len(payload["records"]),
}, indent=2))
if __name__ == "__main__":
main()