Instructions to use ar-mine/cosmos-robometer-private-code with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use ar-mine/cosmos-robometer-private-code with Transformers:
# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("ar-mine/cosmos-robometer-private-code", device_map="auto") - PEFT
How to use ar-mine/cosmos-robometer-private-code with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Add pinned stage2_core_v1 reconstruction and derived action sidecars
Browse files- DATA_SETUP.md +134 -0
- README.md +4 -0
- derived/action_manifests/autoeval_full.jsonl +0 -0
- derived/action_manifests/libero_full.jsonl +0 -0
- derived/action_manifests/racer_pilot.jsonl +0 -0
- derived/action_manifests/roboarena_full_refined.jsonl +0 -0
- derived/action_reports/autoeval_full_validation.json +30 -0
- derived/action_reports/libero_full_validation.json +26 -0
- derived/action_reports/racer_pilot_validation.json +27 -0
- derived/action_reports/roboarena_full_refined_validation.json +27 -0
- derived/action_reports/summary.json +65 -0
- derived/action_sidecars_stage2_action_sidecar_v1.tar +3 -0
- derived/action_sidecars_stage2_action_sidecar_v1.tar.sha256 +3 -0
- manifests/phase2_remediation_pairs_v1.jsonl +0 -0
- manifests/phase2_remediation_pairs_v1_summary.json +19 -19
- manifests/stage2_core_v1_active_archives.json +30 -0
- manifests/stage2_subset_SHA256SUMS +0 -0
- manifests/stage2_subset_inventory.json +0 -0
- scripts/download_stage2_core_v1.py +59 -0
- scripts/extract_stage2_core_v1.py +150 -0
- scripts/package_private_derived_metadata.py +97 -0
- scripts/verify_stage2_links.py +81 -0
DATA_SETUP.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# `stage2_core_v1` data setup and linkage
|
| 2 |
+
|
| 3 |
+
## What is and is not stored here
|
| 4 |
+
|
| 5 |
+
`stage2_core_v1` is this experiment's pinned selection from the official
|
| 6 |
+
`robometer/processed_datasets` repository; it is not an upstream release name.
|
| 7 |
+
The official trajectory `.npz` files are deliberately not duplicated here.
|
| 8 |
+
|
| 9 |
+
This private repository stores only assets that the official download cannot
|
| 10 |
+
recreate by itself:
|
| 11 |
+
|
| 12 |
+
- the frozen 2,689-row Phase 2.1A pair manifest;
|
| 13 |
+
- the exact 4,323-file subset inventory and checksums;
|
| 14 |
+
- recovered action sidecars and portable recovery manifests;
|
| 15 |
+
- download, extraction, linkage, and verification tools.
|
| 16 |
+
|
| 17 |
+
The active profile contains 53,765 trajectories in 13 cache directories. It
|
| 18 |
+
requires 14 physical archive files (RoboArena has two parts), approximately
|
| 19 |
+
106.9 GiB compressed. The quarantined LIBERO Goal-failure archive is excluded.
|
| 20 |
+
|
| 21 |
+
## 1. Download the pinned official archives
|
| 22 |
+
|
| 23 |
+
Choose storage with at least 230 GiB free for archives plus extraction:
|
| 24 |
+
|
| 25 |
+
```bash
|
| 26 |
+
KIT_ROOT=/path/to/cosmos-robometer-private-code
|
| 27 |
+
DATA_ROOT=/path/to/stage2_core_v1
|
| 28 |
+
|
| 29 |
+
cd "$KIT_ROOT"
|
| 30 |
+
uv run --project environment/phase21a_robometer \
|
| 31 |
+
python scripts/download_stage2_core_v1.py \
|
| 32 |
+
--output-dir "$DATA_ROOT/archives"
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
The script downloads only the active profile from:
|
| 36 |
+
|
| 37 |
+
```text
|
| 38 |
+
robometer/processed_datasets
|
| 39 |
+
revision 1a8eb2d279c70964fadeaf8019a77c490c3abe02
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
Do not use Robometer's unmodified `download_processed_datasets.sh` for this
|
| 43 |
+
profile: that script downloads the entire multi-terabyte repository and uses a
|
| 44 |
+
floating revision.
|
| 45 |
+
|
| 46 |
+
## 2. Extract into the path expected by the manifest
|
| 47 |
+
|
| 48 |
+
```bash
|
| 49 |
+
uv run --project environment/phase21a_robometer \
|
| 50 |
+
python scripts/extract_stage2_core_v1.py \
|
| 51 |
+
--archive-root "$DATA_ROOT/archives" \
|
| 52 |
+
--extract-root "$DATA_ROOT/processed_datasets" \
|
| 53 |
+
--output "$DATA_ROOT/extraction_report.json"
|
| 54 |
+
```
|
| 55 |
+
|
| 56 |
+
The frozen pair manifest stores paths beginning with `processed_datasets/`.
|
| 57 |
+
Pass the directory itself to trainers:
|
| 58 |
+
|
| 59 |
+
```bash
|
| 60 |
+
--manifest "$KIT_ROOT/manifests/phase2_remediation_pairs_v1.jsonl" \
|
| 61 |
+
--processed-root "$DATA_ROOT/processed_datasets"
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
No symlink is required. If an existing installation expects a project-local
|
| 65 |
+
path, create a symlink named `processed_datasets` pointing to the extracted
|
| 66 |
+
directory; never copy the 100+ GiB tree merely to satisfy a path convention.
|
| 67 |
+
|
| 68 |
+
## 3. Extract the non-official derived action sidecars
|
| 69 |
+
|
| 70 |
+
```bash
|
| 71 |
+
mkdir -p "$DATA_ROOT/derived"
|
| 72 |
+
tar -xf "$KIT_ROOT/derived/action_sidecars_stage2_action_sidecar_v1.tar" \
|
| 73 |
+
-C "$DATA_ROOT/derived"
|
| 74 |
+
cd "$KIT_ROOT"
|
| 75 |
+
sha256sum --check derived/action_sidecars_stage2_action_sidecar_v1.tar.sha256
|
| 76 |
+
```
|
| 77 |
+
|
| 78 |
+
The archive contains:
|
| 79 |
+
|
| 80 |
+
| Source | Scope | Sidecars | Raw action width |
|
| 81 |
+
|---|---|---:|---:|
|
| 82 |
+
| AutoEval | full attempted scope | 5,939 | 7 |
|
| 83 |
+
| LIBERO success | full | 1,709 | 7 |
|
| 84 |
+
| RoboArena | full, refined | 12,379 | 8 |
|
| 85 |
+
| RACER | pilot: `insert_onto_square_peg` | 593 | 9 |
|
| 86 |
+
|
| 87 |
+
These actions preserve each upstream action space; they are not converted into
|
| 88 |
+
a common canonical representation. Each `.npz` includes `metadata_json`, raw
|
| 89 |
+
actions, aligned actions, and source/alignment indices. RACER's fields are
|
| 90 |
+
`x,y,z,qx,qy,qz,qw,gripper_open,ignore_collision`. For the other sources, use
|
| 91 |
+
the upstream convention recorded in `metadata_json`; do not reinterpret their
|
| 92 |
+
unnamed raw dimensions as Cosmos 6D rotation features.
|
| 93 |
+
|
| 94 |
+
## 4. Join trajectories and action sidecars
|
| 95 |
+
|
| 96 |
+
Join by `stage2_trajectory_id`, never by dataset row order. For example:
|
| 97 |
+
|
| 98 |
+
```text
|
| 99 |
+
official trajectory:
|
| 100 |
+
processed_datasets/<cache_key>/frames/trajectory_<ID>.npz
|
| 101 |
+
|
| 102 |
+
portable action manifest row:
|
| 103 |
+
stage2_trajectory_id = <ID>
|
| 104 |
+
sidecar_path = action_sidecars/<source>/trajectory_<ID>.npz
|
| 105 |
+
```
|
| 106 |
+
|
| 107 |
+
Resolve `sidecar_path` relative to `$DATA_ROOT/derived`. Rows without a
|
| 108 |
+
`sidecar_path` were not recovered and retain an explicit status such as
|
| 109 |
+
`source_has_no_actions` or `rejected_refinement_no_consensus`.
|
| 110 |
+
|
| 111 |
+
`Robometer-Low-LoRA` does not consume the action sidecars; they are packaged for
|
| 112 |
+
later action-conditioned Cosmos experiments and provenance auditing.
|
| 113 |
+
|
| 114 |
+
## 5. Verify the complete association
|
| 115 |
+
|
| 116 |
+
Fast path/link check:
|
| 117 |
+
|
| 118 |
+
```bash
|
| 119 |
+
uv run --project environment/phase21a_robometer \
|
| 120 |
+
python scripts/verify_stage2_links.py \
|
| 121 |
+
--manifest "$KIT_ROOT/manifests/phase2_remediation_pairs_v1.jsonl" \
|
| 122 |
+
--processed-root "$DATA_ROOT/processed_datasets" \
|
| 123 |
+
--action-manifest-dir "$KIT_ROOT/derived/action_manifests" \
|
| 124 |
+
--derived-root "$DATA_ROOT/derived"
|
| 125 |
+
```
|
| 126 |
+
|
| 127 |
+
Full byte-level verification of the 4,323 training trajectories adds:
|
| 128 |
+
|
| 129 |
+
```bash
|
| 130 |
+
--checksums "$KIT_ROOT/manifests/stage2_subset_SHA256SUMS"
|
| 131 |
+
```
|
| 132 |
+
|
| 133 |
+
Expected link-check totals are 2,689 pair rows, 4,323 unique official frame
|
| 134 |
+
files, 23,359 action-manifest rows, and 20,620 resolved action sidecars.
|
README.md
CHANGED
|
@@ -53,6 +53,10 @@ Robometer processed-data repository and the frozen dataset manifest.
|
|
| 53 |
See [TRAINING_MANUAL.md](TRAINING_MANUAL.md). The frozen LoRA configuration is
|
| 54 |
`configs/phase21a_robometer_low_lora_train_v2.yaml`.
|
| 55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
## Current support boundary
|
| 57 |
|
| 58 |
The LoRA trainer is runnable and validated at micro-batch 32, gradient
|
|
|
|
| 53 |
See [TRAINING_MANUAL.md](TRAINING_MANUAL.md). The frozen LoRA configuration is
|
| 54 |
`configs/phase21a_robometer_low_lora_train_v2.yaml`.
|
| 55 |
|
| 56 |
+
For the pinned official `stage2_core_v1` download, extraction, frozen-manifest
|
| 57 |
+
association, and optional recovered-action linkage, see
|
| 58 |
+
[DATA_SETUP.md](DATA_SETUP.md).
|
| 59 |
+
|
| 60 |
## Current support boundary
|
| 61 |
|
| 62 |
The LoRA trainer is runnable and validated at micro-batch 32, gradient
|
derived/action_manifests/autoeval_full.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
derived/action_manifests/libero_full.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
derived/action_manifests/racer_pilot.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
derived/action_manifests/roboarena_full_refined.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
derived/action_reports/autoeval_full_validation.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"action_dims": {
|
| 3 |
+
"7": 5939
|
| 4 |
+
},
|
| 5 |
+
"aligned_action_steps": {
|
| 6 |
+
"max": 32,
|
| 7 |
+
"median": 32.0,
|
| 8 |
+
"min": 10
|
| 9 |
+
},
|
| 10 |
+
"error_count": 0,
|
| 11 |
+
"error_examples": [],
|
| 12 |
+
"manifest": "experiments/cosmos3_edge_reasoner_robometer_route_a_v1/manifests/action_recovery_v1/autoeval_full.jsonl",
|
| 13 |
+
"manifest_rows": 8677,
|
| 14 |
+
"raw_action_steps": {
|
| 15 |
+
"max": 100,
|
| 16 |
+
"median": 70.0,
|
| 17 |
+
"min": 10
|
| 18 |
+
},
|
| 19 |
+
"recovered_rows": 5939,
|
| 20 |
+
"status": "pass",
|
| 21 |
+
"status_counts": {
|
| 22 |
+
"recovered": 5919,
|
| 23 |
+
"recovered_refined": 20,
|
| 24 |
+
"rejected_refinement_no_consensus": 20,
|
| 25 |
+
"source_has_no_actions": 2647,
|
| 26 |
+
"source_has_no_actions_refined": 71
|
| 27 |
+
},
|
| 28 |
+
"unique_sidecar_paths": 5939,
|
| 29 |
+
"unique_trajectory_ids": 5939
|
| 30 |
+
}
|
derived/action_reports/libero_full_validation.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"action_dims": {
|
| 3 |
+
"7": 1709
|
| 4 |
+
},
|
| 5 |
+
"aligned_action_steps": {
|
| 6 |
+
"max": 32,
|
| 7 |
+
"median": 32.0,
|
| 8 |
+
"min": 32
|
| 9 |
+
},
|
| 10 |
+
"error_count": 0,
|
| 11 |
+
"error_examples": [],
|
| 12 |
+
"manifest": "experiments/cosmos3_edge_reasoner_robometer_route_a_v1/manifests/action_recovery_v1/libero_full.jsonl",
|
| 13 |
+
"manifest_rows": 1709,
|
| 14 |
+
"raw_action_steps": {
|
| 15 |
+
"max": 505,
|
| 16 |
+
"median": 141.0,
|
| 17 |
+
"min": 75
|
| 18 |
+
},
|
| 19 |
+
"recovered_rows": 1709,
|
| 20 |
+
"status": "pass",
|
| 21 |
+
"status_counts": {
|
| 22 |
+
"recovered": 1709
|
| 23 |
+
},
|
| 24 |
+
"unique_sidecar_paths": 1709,
|
| 25 |
+
"unique_trajectory_ids": 1709
|
| 26 |
+
}
|
derived/action_reports/racer_pilot_validation.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"action_dims": {
|
| 3 |
+
"9": 593
|
| 4 |
+
},
|
| 5 |
+
"aligned_action_steps": {
|
| 6 |
+
"max": 6,
|
| 7 |
+
"median": 6.0,
|
| 8 |
+
"min": 2
|
| 9 |
+
},
|
| 10 |
+
"error_count": 0,
|
| 11 |
+
"error_examples": [],
|
| 12 |
+
"manifest": "experiments/cosmos3_edge_reasoner_robometer_route_a_v1/manifests/action_recovery_v1/racer_pilot.jsonl",
|
| 13 |
+
"manifest_rows": 594,
|
| 14 |
+
"raw_action_steps": {
|
| 15 |
+
"max": 8,
|
| 16 |
+
"median": 8.0,
|
| 17 |
+
"min": 6
|
| 18 |
+
},
|
| 19 |
+
"recovered_rows": 593,
|
| 20 |
+
"status": "pass",
|
| 21 |
+
"status_counts": {
|
| 22 |
+
"recovered": 593,
|
| 23 |
+
"rejected_alignment": 1
|
| 24 |
+
},
|
| 25 |
+
"unique_sidecar_paths": 593,
|
| 26 |
+
"unique_trajectory_ids": 593
|
| 27 |
+
}
|
derived/action_reports/roboarena_full_refined_validation.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"action_dims": {
|
| 3 |
+
"8": 12379
|
| 4 |
+
},
|
| 5 |
+
"aligned_action_steps": {
|
| 6 |
+
"max": 32,
|
| 7 |
+
"median": 32.0,
|
| 8 |
+
"min": 18
|
| 9 |
+
},
|
| 10 |
+
"error_count": 0,
|
| 11 |
+
"error_examples": [],
|
| 12 |
+
"manifest": "experiments/cosmos3_edge_reasoner_robometer_route_a_v1/manifests/action_recovery_v1/roboarena_full_refined.jsonl",
|
| 13 |
+
"manifest_rows": 12379,
|
| 14 |
+
"raw_action_steps": {
|
| 15 |
+
"max": 800,
|
| 16 |
+
"median": 400.0,
|
| 17 |
+
"min": 17
|
| 18 |
+
},
|
| 19 |
+
"recovered_rows": 12379,
|
| 20 |
+
"status": "pass",
|
| 21 |
+
"status_counts": {
|
| 22 |
+
"recovered": 12326,
|
| 23 |
+
"recovered_refined": 53
|
| 24 |
+
},
|
| 25 |
+
"unique_sidecar_paths": 12379,
|
| 26 |
+
"unique_trajectory_ids": 12379
|
| 27 |
+
}
|
derived/action_reports/summary.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"created_at": "2026-08-26T17:15:00+08:00",
|
| 3 |
+
"policy": {
|
| 4 |
+
"canonicalized_during_recovery": false,
|
| 5 |
+
"imputed_actions": false,
|
| 6 |
+
"mutated_frozen_stage2_cache": false,
|
| 7 |
+
"preserved_raw_action_space": true
|
| 8 |
+
},
|
| 9 |
+
"profile": "stage2_core_v1",
|
| 10 |
+
"results": {
|
| 11 |
+
"autoeval": {
|
| 12 |
+
"action_dim": 7,
|
| 13 |
+
"attempted_rows": 8677,
|
| 14 |
+
"recovered_rows": 5939,
|
| 15 |
+
"rejected_rows": 20,
|
| 16 |
+
"scope": "full",
|
| 17 |
+
"source_has_no_action_rows": 2718,
|
| 18 |
+
"validation_errors": 0
|
| 19 |
+
},
|
| 20 |
+
"libero_success": {
|
| 21 |
+
"action_dim": 7,
|
| 22 |
+
"attempted_rows": 1709,
|
| 23 |
+
"recovered_rows": 1709,
|
| 24 |
+
"rejected_rows": 0,
|
| 25 |
+
"scope": "full",
|
| 26 |
+
"source_has_no_action_rows": 0,
|
| 27 |
+
"validation_errors": 0
|
| 28 |
+
},
|
| 29 |
+
"racer": {
|
| 30 |
+
"action_dim": 9,
|
| 31 |
+
"attempted_rows": 594,
|
| 32 |
+
"expected_full_stage2_rows": 29115,
|
| 33 |
+
"recovered_rows": 593,
|
| 34 |
+
"rejected_rows": 1,
|
| 35 |
+
"scope": "pilot_insert_onto_square_peg",
|
| 36 |
+
"source_has_no_action_rows": 0,
|
| 37 |
+
"validation_errors": 0
|
| 38 |
+
},
|
| 39 |
+
"roboarena": {
|
| 40 |
+
"action_dim": 8,
|
| 41 |
+
"attempted_rows": 12379,
|
| 42 |
+
"recovered_rows": 12379,
|
| 43 |
+
"rejected_rows": 0,
|
| 44 |
+
"scope": "full",
|
| 45 |
+
"source_has_no_action_rows": 0,
|
| 46 |
+
"validation_errors": 0
|
| 47 |
+
}
|
| 48 |
+
},
|
| 49 |
+
"schema_version": "stage2_action_sidecar_v1",
|
| 50 |
+
"totals_for_attempted_scope": {
|
| 51 |
+
"attempted_rows": 23359,
|
| 52 |
+
"recovered_rows": 20620,
|
| 53 |
+
"rejected_rows": 21,
|
| 54 |
+
"source_has_no_action_rows": 2718,
|
| 55 |
+
"validation_errors": 0
|
| 56 |
+
},
|
| 57 |
+
"unattempted_stage2_rows": {
|
| 58 |
+
"fino_net_exact_action_unavailable": 229,
|
| 59 |
+
"libero_failure_exact_action_unavailable": 1473,
|
| 60 |
+
"metaworld_provenance_pending": 100,
|
| 61 |
+
"motif_exact_action_unavailable": 83,
|
| 62 |
+
"racer_remaining_full_scope": 28521,
|
| 63 |
+
"total": 30406
|
| 64 |
+
}
|
| 65 |
+
}
|
derived/action_sidecars_stage2_action_sidecar_v1.tar
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2b70561099696a769a6d6ee750270b48ab3ded47a44470173bf753a329a39a4e
|
| 3 |
+
size 455188480
|
derived/action_sidecars_stage2_action_sidecar_v1.tar.sha256
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5580061f5fd94ef18bb2a6ceb01f2bf1e7945634c27e3ba5df4685b8f4fa1f26
|
| 3 |
+
size 119
|
manifests/phase2_remediation_pairs_v1.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
manifests/phase2_remediation_pairs_v1_summary.json
CHANGED
|
@@ -1,26 +1,26 @@
|
|
| 1 |
{
|
| 2 |
-
"status": "pass",
|
| 3 |
-
"role": "phase2_five_percent_id_only_remediation",
|
| 4 |
-
"seed": 1701,
|
| 5 |
-
"requested_confirmation_fraction_of_full_stream": 0.2,
|
| 6 |
-
"pair_count": 2689,
|
| 7 |
-
"original_stream_pair_count": 538,
|
| 8 |
-
"train_pair_count": 2021,
|
| 9 |
-
"original_dev_pair_count": 108,
|
| 10 |
-
"confirmation_dev_pair_count": 538,
|
| 11 |
-
"excluded_original_dev_component_pair_count": 22,
|
| 12 |
-
"component_count": 2393,
|
| 13 |
-
"eligible_confirmation_component_count": 1874,
|
| 14 |
-
"selected_confirmation_component_count": 495,
|
| 15 |
-
"original_dev_preserved_verbatim": true,
|
| 16 |
-
"five_percent_is_exact_one_percent_prefix_extension": true,
|
| 17 |
-
"confirmation_ids_seen_in_original_stream": 0,
|
| 18 |
"active_split_trajectory_id_overlaps": {
|
| 19 |
-
"
|
| 20 |
"train_confirmation_dev": 0,
|
| 21 |
-
"
|
| 22 |
},
|
| 23 |
"active_unique_feature_sides": 5181,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
"manifest": "manifests/phase2_remediation_pairs_v1.jsonl",
|
| 25 |
-
"manifest_sha256": "c77642e3d34177d1bfbcebe8c97cdf0af952c83d95a677cf42d95426b6d49204"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
}
|
|
|
|
| 1 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
"active_split_trajectory_id_overlaps": {
|
| 3 |
+
"dev_confirmation_dev": 0,
|
| 4 |
"train_confirmation_dev": 0,
|
| 5 |
+
"train_dev": 0
|
| 6 |
},
|
| 7 |
"active_unique_feature_sides": 5181,
|
| 8 |
+
"component_count": 2393,
|
| 9 |
+
"confirmation_dev_pair_count": 538,
|
| 10 |
+
"confirmation_ids_seen_in_original_stream": 0,
|
| 11 |
+
"eligible_confirmation_component_count": 1874,
|
| 12 |
+
"excluded_original_dev_component_pair_count": 22,
|
| 13 |
+
"five_percent_is_exact_one_percent_prefix_extension": true,
|
| 14 |
"manifest": "manifests/phase2_remediation_pairs_v1.jsonl",
|
| 15 |
+
"manifest_sha256": "c77642e3d34177d1bfbcebe8c97cdf0af952c83d95a677cf42d95426b6d49204",
|
| 16 |
+
"original_dev_pair_count": 108,
|
| 17 |
+
"original_dev_preserved_verbatim": true,
|
| 18 |
+
"original_stream_pair_count": 538,
|
| 19 |
+
"pair_count": 2689,
|
| 20 |
+
"requested_confirmation_fraction_of_full_stream": 0.2,
|
| 21 |
+
"role": "phase2_five_percent_id_only_remediation",
|
| 22 |
+
"seed": 1701,
|
| 23 |
+
"selected_confirmation_component_count": 495,
|
| 24 |
+
"status": "pass",
|
| 25 |
+
"train_pair_count": 2021
|
| 26 |
}
|
manifests/stage2_core_v1_active_archives.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema_version": "stage2_core_v1_active_archives_v1",
|
| 3 |
+
"repo_id": "robometer/processed_datasets",
|
| 4 |
+
"revision": "1a8eb2d279c70964fadeaf8019a77c490c3abe02",
|
| 5 |
+
"profile": "stage2_core_v1_active",
|
| 6 |
+
"physical_archive_files": 14,
|
| 7 |
+
"logical_cache_directories": 13,
|
| 8 |
+
"expected_trajectories": 53765,
|
| 9 |
+
"total_bytes": 114772469760,
|
| 10 |
+
"total_gib": 106.89019203186035,
|
| 11 |
+
"quarantined_and_not_downloaded": [
|
| 12 |
+
"ykorkmaz_libero_failure_rfm_libero_goal_failure.tar"
|
| 13 |
+
],
|
| 14 |
+
"archives": [
|
| 15 |
+
{"name": "abraranwar_libero_rfm_libero256_10.tar", "bytes": 743413760},
|
| 16 |
+
{"name": "abraranwar_libero_rfm_libero256_goal.tar", "bytes": 818688000},
|
| 17 |
+
{"name": "abraranwar_libero_rfm_libero256_object.tar", "bytes": 1179627520},
|
| 18 |
+
{"name": "abraranwar_libero_rfm_libero256_spatial.tar", "bytes": 796948480},
|
| 19 |
+
{"name": "aliangdw_metaworld_metaworld_train.tar", "bytes": 233943040},
|
| 20 |
+
{"name": "jesbu1_auto_eval_rfm_auto_eval_rfm.tar", "bytes": 33058539520},
|
| 21 |
+
{"name": "jesbu1_fino_net_rfm_fino_net.tar", "bytes": 865863680},
|
| 22 |
+
{"name": "jesbu1_motif_rfm_motif_rfm.tar", "bytes": 162570240},
|
| 23 |
+
{"name": "jesbu1_racer_rfm_racer_train.tar", "bytes": 15018711040},
|
| 24 |
+
{"name": "jesbu1_roboarena_0825_rfm_roboarena.tar.part-aa", "bytes": 32212254720},
|
| 25 |
+
{"name": "jesbu1_roboarena_0825_rfm_roboarena.tar.part-ab", "bytes": 26715269120},
|
| 26 |
+
{"name": "ykorkmaz_libero_failure_rfm_libero_10_failure.tar", "bytes": 968499200},
|
| 27 |
+
{"name": "ykorkmaz_libero_failure_rfm_libero_object_failure.tar", "bytes": 1107578880},
|
| 28 |
+
{"name": "ykorkmaz_libero_failure_rfm_libero_spatial_failure.tar", "bytes": 890562560}
|
| 29 |
+
]
|
| 30 |
+
}
|
manifests/stage2_subset_SHA256SUMS
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
manifests/stage2_subset_inventory.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
scripts/download_stage2_core_v1.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Download the pinned active stage2_core_v1 archive profile from Robometer."""
|
| 3 |
+
|
| 4 |
+
from __future__ import annotations
|
| 5 |
+
|
| 6 |
+
import argparse
|
| 7 |
+
import json
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
from huggingface_hub import snapshot_download
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
REPO_ID = "robometer/processed_datasets"
|
| 14 |
+
REVISION = "1a8eb2d279c70964fadeaf8019a77c490c3abe02"
|
| 15 |
+
ACTIVE_ARCHIVES = (
|
| 16 |
+
"abraranwar_libero_rfm_libero256_10.tar",
|
| 17 |
+
"abraranwar_libero_rfm_libero256_goal.tar",
|
| 18 |
+
"abraranwar_libero_rfm_libero256_object.tar",
|
| 19 |
+
"abraranwar_libero_rfm_libero256_spatial.tar",
|
| 20 |
+
"aliangdw_metaworld_metaworld_train.tar",
|
| 21 |
+
"jesbu1_auto_eval_rfm_auto_eval_rfm.tar",
|
| 22 |
+
"jesbu1_fino_net_rfm_fino_net.tar",
|
| 23 |
+
"jesbu1_motif_rfm_motif_rfm.tar",
|
| 24 |
+
"jesbu1_racer_rfm_racer_train.tar",
|
| 25 |
+
"jesbu1_roboarena_0825_rfm_roboarena.tar.part-aa",
|
| 26 |
+
"jesbu1_roboarena_0825_rfm_roboarena.tar.part-ab",
|
| 27 |
+
"ykorkmaz_libero_failure_rfm_libero_10_failure.tar",
|
| 28 |
+
"ykorkmaz_libero_failure_rfm_libero_object_failure.tar",
|
| 29 |
+
"ykorkmaz_libero_failure_rfm_libero_spatial_failure.tar",
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def main() -> None:
|
| 34 |
+
parser = argparse.ArgumentParser()
|
| 35 |
+
parser.add_argument("--output-dir", type=Path, required=True)
|
| 36 |
+
args = parser.parse_args()
|
| 37 |
+
args.output_dir.mkdir(parents=True, exist_ok=True)
|
| 38 |
+
location = snapshot_download(
|
| 39 |
+
repo_id=REPO_ID,
|
| 40 |
+
repo_type="dataset",
|
| 41 |
+
revision=REVISION,
|
| 42 |
+
allow_patterns=list(ACTIVE_ARCHIVES),
|
| 43 |
+
local_dir=args.output_dir,
|
| 44 |
+
)
|
| 45 |
+
missing = [name for name in ACTIVE_ARCHIVES if not (args.output_dir / name).is_file()]
|
| 46 |
+
if missing:
|
| 47 |
+
raise FileNotFoundError(f"download completed with missing archives: {missing}")
|
| 48 |
+
print(json.dumps({
|
| 49 |
+
"status": "complete",
|
| 50 |
+
"repo_id": REPO_ID,
|
| 51 |
+
"revision": REVISION,
|
| 52 |
+
"profile": "stage2_core_v1_active",
|
| 53 |
+
"archive_files": len(ACTIVE_ARCHIVES),
|
| 54 |
+
"local_dir": str(Path(location).resolve()),
|
| 55 |
+
}, indent=2))
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
if __name__ == "__main__":
|
| 59 |
+
main()
|
scripts/extract_stage2_core_v1.py
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Safely extract the pinned stage2_core_v1 archive set without overwrites."""
|
| 3 |
+
|
| 4 |
+
from __future__ import annotations
|
| 5 |
+
|
| 6 |
+
import argparse
|
| 7 |
+
import json
|
| 8 |
+
import subprocess
|
| 9 |
+
import time
|
| 10 |
+
from datetime import datetime
|
| 11 |
+
from pathlib import Path
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
EXPECTED_ARCHIVES = (
|
| 15 |
+
"abraranwar_libero_rfm_libero256_10.tar",
|
| 16 |
+
"abraranwar_libero_rfm_libero256_goal.tar",
|
| 17 |
+
"abraranwar_libero_rfm_libero256_object.tar",
|
| 18 |
+
"abraranwar_libero_rfm_libero256_spatial.tar",
|
| 19 |
+
"aliangdw_metaworld_metaworld_train.tar",
|
| 20 |
+
"jesbu1_auto_eval_rfm_auto_eval_rfm.tar",
|
| 21 |
+
"jesbu1_fino_net_rfm_fino_net.tar",
|
| 22 |
+
"jesbu1_motif_rfm_motif_rfm.tar",
|
| 23 |
+
"jesbu1_racer_rfm_racer_train.tar",
|
| 24 |
+
"jesbu1_roboarena_0825_rfm_roboarena.tar.part-aa",
|
| 25 |
+
"jesbu1_roboarena_0825_rfm_roboarena.tar.part-ab",
|
| 26 |
+
"ykorkmaz_libero_failure_rfm_libero_10_failure.tar",
|
| 27 |
+
"ykorkmaz_libero_failure_rfm_libero_object_failure.tar",
|
| 28 |
+
"ykorkmaz_libero_failure_rfm_libero_spatial_failure.tar",
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def parse_args() -> argparse.Namespace:
|
| 33 |
+
parser = argparse.ArgumentParser()
|
| 34 |
+
parser.add_argument("--archive-root", type=Path, required=True)
|
| 35 |
+
parser.add_argument("--extract-root", type=Path, required=True)
|
| 36 |
+
parser.add_argument("--output", type=Path, required=True)
|
| 37 |
+
return parser.parse_args()
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
def cache_key(archive_name: str) -> str:
|
| 41 |
+
return archive_name.split(".tar", 1)[0]
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def tar_command(extract_root: Path, archive: Path | None = None) -> list[str]:
|
| 45 |
+
archive_arg = str(archive) if archive is not None else "-"
|
| 46 |
+
return [
|
| 47 |
+
"tar",
|
| 48 |
+
"-xf",
|
| 49 |
+
archive_arg,
|
| 50 |
+
"-C",
|
| 51 |
+
str(extract_root),
|
| 52 |
+
"--no-same-owner",
|
| 53 |
+
"--no-same-permissions",
|
| 54 |
+
]
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def main() -> None:
|
| 58 |
+
args = parse_args()
|
| 59 |
+
archive_root = args.archive_root.resolve()
|
| 60 |
+
extract_root = args.extract_root.resolve()
|
| 61 |
+
missing = [
|
| 62 |
+
name for name in EXPECTED_ARCHIVES if not (archive_root / name).is_file()
|
| 63 |
+
]
|
| 64 |
+
if missing:
|
| 65 |
+
raise FileNotFoundError(f"Missing expected archives: {missing}")
|
| 66 |
+
|
| 67 |
+
expected_names = set(EXPECTED_ARCHIVES)
|
| 68 |
+
observed_names = {
|
| 69 |
+
path.name
|
| 70 |
+
for path in archive_root.iterdir()
|
| 71 |
+
if path.is_file() and (".tar" in path.name)
|
| 72 |
+
}
|
| 73 |
+
if observed_names != expected_names:
|
| 74 |
+
raise RuntimeError(
|
| 75 |
+
"Archive set differs from the pinned contract: "
|
| 76 |
+
f"missing={sorted(expected_names - observed_names)}, "
|
| 77 |
+
f"unexpected={sorted(observed_names - expected_names)}"
|
| 78 |
+
)
|
| 79 |
+
|
| 80 |
+
extract_root.mkdir(parents=True, exist_ok=True)
|
| 81 |
+
logical_archives = [
|
| 82 |
+
name for name in EXPECTED_ARCHIVES if not name.endswith(".part-ab")
|
| 83 |
+
]
|
| 84 |
+
target_keys = [cache_key(name) for name in logical_archives]
|
| 85 |
+
existing = [key for key in target_keys if (extract_root / key).exists()]
|
| 86 |
+
if existing:
|
| 87 |
+
raise FileExistsError(
|
| 88 |
+
f"Refusing to overwrite existing extracted cache directories: {existing}"
|
| 89 |
+
)
|
| 90 |
+
|
| 91 |
+
started = time.perf_counter()
|
| 92 |
+
records = []
|
| 93 |
+
for name in logical_archives:
|
| 94 |
+
item_started = time.perf_counter()
|
| 95 |
+
path = archive_root / name
|
| 96 |
+
key = cache_key(name)
|
| 97 |
+
print(json.dumps({"event": "extract_start", "archive": name}), flush=True)
|
| 98 |
+
if name.endswith(".part-aa"):
|
| 99 |
+
part_ab = archive_root / name.removesuffix(".part-aa")
|
| 100 |
+
part_ab = part_ab.with_name(part_ab.name + ".part-ab")
|
| 101 |
+
cat_process = subprocess.Popen(
|
| 102 |
+
["cat", str(path), str(part_ab)], stdout=subprocess.PIPE
|
| 103 |
+
)
|
| 104 |
+
if cat_process.stdout is None:
|
| 105 |
+
raise RuntimeError("Failed to open split-archive stream")
|
| 106 |
+
tar_result = subprocess.run(
|
| 107 |
+
tar_command(extract_root),
|
| 108 |
+
stdin=cat_process.stdout,
|
| 109 |
+
check=False,
|
| 110 |
+
)
|
| 111 |
+
cat_process.stdout.close()
|
| 112 |
+
cat_returncode = cat_process.wait()
|
| 113 |
+
if tar_result.returncode or cat_returncode:
|
| 114 |
+
raise RuntimeError(
|
| 115 |
+
f"Split extraction failed: tar={tar_result.returncode}, "
|
| 116 |
+
f"cat={cat_returncode}"
|
| 117 |
+
)
|
| 118 |
+
else:
|
| 119 |
+
subprocess.run(tar_command(extract_root, path), check=True)
|
| 120 |
+
|
| 121 |
+
target = extract_root / key
|
| 122 |
+
if not target.is_dir():
|
| 123 |
+
raise RuntimeError(
|
| 124 |
+
f"Archive did not create its expected cache root: {target}"
|
| 125 |
+
)
|
| 126 |
+
record = {
|
| 127 |
+
"archive": name,
|
| 128 |
+
"cache_key": key,
|
| 129 |
+
"seconds": time.perf_counter() - item_started,
|
| 130 |
+
}
|
| 131 |
+
records.append(record)
|
| 132 |
+
print(json.dumps({"event": "extract_complete", **record}), flush=True)
|
| 133 |
+
|
| 134 |
+
result = {
|
| 135 |
+
"status": "pass",
|
| 136 |
+
"created_at": datetime.now().astimezone().isoformat(),
|
| 137 |
+
"archive_root": str(archive_root),
|
| 138 |
+
"extract_root": str(extract_root),
|
| 139 |
+
"physical_archive_files": len(EXPECTED_ARCHIVES),
|
| 140 |
+
"logical_cache_directories": len(target_keys),
|
| 141 |
+
"total_seconds": time.perf_counter() - started,
|
| 142 |
+
"records": records,
|
| 143 |
+
}
|
| 144 |
+
args.output.parent.mkdir(parents=True, exist_ok=True)
|
| 145 |
+
args.output.write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8")
|
| 146 |
+
print(json.dumps({"event": "summary", **result}), flush=True)
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
if __name__ == "__main__":
|
| 150 |
+
main()
|
scripts/package_private_derived_metadata.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Create portable copies of locally derived manifests and reports."""
|
| 3 |
+
|
| 4 |
+
from __future__ import annotations
|
| 5 |
+
|
| 6 |
+
import argparse
|
| 7 |
+
import json
|
| 8 |
+
import shutil
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
ACTION_MANIFESTS = {
|
| 13 |
+
"autoeval_full.jsonl": "autoeval",
|
| 14 |
+
"libero_full.jsonl": "libero_success",
|
| 15 |
+
"roboarena_full_refined.jsonl": "roboarena",
|
| 16 |
+
"racer_pilot.jsonl": "racer_pilot",
|
| 17 |
+
}
|
| 18 |
+
ACTION_REPORTS = (
|
| 19 |
+
"summary.json",
|
| 20 |
+
"autoeval_full_validation.json",
|
| 21 |
+
"libero_full_validation.json",
|
| 22 |
+
"roboarena_full_refined_validation.json",
|
| 23 |
+
"racer_pilot_validation.json",
|
| 24 |
+
)
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def portable(value, experiment_root: Path):
|
| 28 |
+
if isinstance(value, dict):
|
| 29 |
+
return {key: portable(item, experiment_root) for key, item in value.items()}
|
| 30 |
+
if isinstance(value, list):
|
| 31 |
+
return [portable(item, experiment_root) for item in value]
|
| 32 |
+
if not isinstance(value, str):
|
| 33 |
+
return value
|
| 34 |
+
if "/action_labels/stage2_action_sidecar_v1/" in value:
|
| 35 |
+
return "action_sidecars/" + value.split("/action_labels/stage2_action_sidecar_v1/", 1)[1]
|
| 36 |
+
racer_marker = "/artifacts/action_recovery_v1/racer_pilot/"
|
| 37 |
+
if racer_marker in value:
|
| 38 |
+
return "action_sidecars/racer_pilot/" + value.split(racer_marker, 1)[1]
|
| 39 |
+
if "/action_sources/" in value:
|
| 40 |
+
return "upstream_raw/" + value.split("/action_sources/", 1)[1]
|
| 41 |
+
root_text = str(experiment_root.resolve()) + "/"
|
| 42 |
+
if value.startswith(root_text):
|
| 43 |
+
return value[len(root_text):]
|
| 44 |
+
return value
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def rewrite_json(source: Path, target: Path, experiment_root: Path) -> None:
|
| 48 |
+
payload = portable(json.loads(source.read_text()), experiment_root)
|
| 49 |
+
target.parent.mkdir(parents=True, exist_ok=True)
|
| 50 |
+
target.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def rewrite_jsonl(source: Path, target: Path, experiment_root: Path, source_name: str) -> None:
|
| 54 |
+
target.parent.mkdir(parents=True, exist_ok=True)
|
| 55 |
+
output = []
|
| 56 |
+
for line in source.read_text().splitlines():
|
| 57 |
+
if not line:
|
| 58 |
+
continue
|
| 59 |
+
row = portable(json.loads(line), experiment_root)
|
| 60 |
+
if "sidecar_path" in row:
|
| 61 |
+
row["sidecar_path"] = f"action_sidecars/{source_name}/trajectory_{row['stage2_trajectory_id']}.npz"
|
| 62 |
+
output.append(json.dumps(row, sort_keys=True) + "\n")
|
| 63 |
+
target.write_text("".join(output))
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def main() -> None:
|
| 67 |
+
parser = argparse.ArgumentParser()
|
| 68 |
+
parser.add_argument("--experiment-root", type=Path, required=True)
|
| 69 |
+
parser.add_argument("--dataset-metadata-root", type=Path, required=True)
|
| 70 |
+
parser.add_argument("--output-root", type=Path, required=True)
|
| 71 |
+
args = parser.parse_args()
|
| 72 |
+
experiment = args.experiment_root.resolve()
|
| 73 |
+
output = args.output_root.resolve()
|
| 74 |
+
|
| 75 |
+
manifests = experiment / "manifests"
|
| 76 |
+
shutil.copy2(manifests / "phase2_remediation_pairs_v1.jsonl", output / "manifests/phase2_remediation_pairs_v1.jsonl")
|
| 77 |
+
rewrite_json(manifests / "phase2_remediation_pairs_v1_summary.json", output / "manifests/phase2_remediation_pairs_v1_summary.json", experiment)
|
| 78 |
+
action_source = manifests / "action_recovery_v1"
|
| 79 |
+
for name, source_name in ACTION_MANIFESTS.items():
|
| 80 |
+
rewrite_jsonl(action_source / name, output / "derived/action_manifests" / name, experiment, source_name)
|
| 81 |
+
report_source = experiment / "reports/action_recovery_v1"
|
| 82 |
+
for name in ACTION_REPORTS:
|
| 83 |
+
rewrite_json(report_source / name, output / "derived/action_reports" / name, experiment)
|
| 84 |
+
|
| 85 |
+
inventory_source = args.dataset_metadata_root / "phase21a_data_inventory.json"
|
| 86 |
+
inventory = json.loads(inventory_source.read_text())
|
| 87 |
+
inventory["manifest"] = "manifests/phase2_remediation_pairs_v1.jsonl"
|
| 88 |
+
inventory["output_dir"] = "."
|
| 89 |
+
(output / "manifests/stage2_subset_inventory.json").write_text(
|
| 90 |
+
json.dumps(inventory, indent=2, sort_keys=True) + "\n"
|
| 91 |
+
)
|
| 92 |
+
shutil.copy2(args.dataset_metadata_root / "SHA256SUMS", output / "manifests/stage2_subset_SHA256SUMS")
|
| 93 |
+
print(json.dumps({"status": "complete", "output_root": str(output)}, indent=2))
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
if __name__ == "__main__":
|
| 97 |
+
main()
|
scripts/verify_stage2_links.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Verify that frozen pair/action manifests resolve against reconstructed data."""
|
| 3 |
+
|
| 4 |
+
from __future__ import annotations
|
| 5 |
+
|
| 6 |
+
import argparse
|
| 7 |
+
import hashlib
|
| 8 |
+
import json
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
def digest(path: Path) -> str:
|
| 13 |
+
result = hashlib.sha256()
|
| 14 |
+
with path.open("rb") as stream:
|
| 15 |
+
for block in iter(lambda: stream.read(8 * 1024 * 1024), b""):
|
| 16 |
+
result.update(block)
|
| 17 |
+
return result.hexdigest()
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
def main() -> None:
|
| 21 |
+
parser = argparse.ArgumentParser()
|
| 22 |
+
parser.add_argument("--manifest", type=Path, required=True)
|
| 23 |
+
parser.add_argument("--processed-root", type=Path, required=True)
|
| 24 |
+
parser.add_argument("--checksums", type=Path)
|
| 25 |
+
parser.add_argument("--action-manifest-dir", type=Path)
|
| 26 |
+
parser.add_argument("--derived-root", type=Path)
|
| 27 |
+
args = parser.parse_args()
|
| 28 |
+
|
| 29 |
+
rows = [json.loads(line) for line in args.manifest.read_text().splitlines() if line]
|
| 30 |
+
references: set[Path] = set()
|
| 31 |
+
for row in rows:
|
| 32 |
+
for role in ("chosen", "rejected"):
|
| 33 |
+
relative = Path(str(row[role]["source_frame_file"]))
|
| 34 |
+
parts = relative.parts[1:] if relative.parts[:1] in ((".",), ("processed_datasets",)) else relative.parts
|
| 35 |
+
if relative.parts[:1] == (".",) and parts[:1] == ("processed_datasets",):
|
| 36 |
+
parts = parts[1:]
|
| 37 |
+
references.add(Path(*parts))
|
| 38 |
+
missing = [str(path) for path in sorted(references) if not (args.processed_root / path).is_file()]
|
| 39 |
+
if missing:
|
| 40 |
+
raise FileNotFoundError(f"missing {len(missing)} manifest frame files; examples={missing[:10]}")
|
| 41 |
+
if len(rows) != 2689 or len(references) != 4323:
|
| 42 |
+
raise RuntimeError(f"unexpected frozen counts: rows={len(rows)} files={len(references)}")
|
| 43 |
+
|
| 44 |
+
checksum_count = 0
|
| 45 |
+
if args.checksums:
|
| 46 |
+
for line in args.checksums.read_text().splitlines():
|
| 47 |
+
expected, relative = line.split(maxsplit=1)
|
| 48 |
+
relative_path = Path(relative.strip())
|
| 49 |
+
parts = relative_path.parts[1:] if relative_path.parts[:1] == ("processed_datasets",) else relative_path.parts
|
| 50 |
+
target = args.processed_root / Path(*parts)
|
| 51 |
+
if digest(target) != expected:
|
| 52 |
+
raise RuntimeError(f"SHA256 mismatch: {target}")
|
| 53 |
+
checksum_count += 1
|
| 54 |
+
|
| 55 |
+
action_rows = action_files = 0
|
| 56 |
+
if args.action_manifest_dir or args.derived_root:
|
| 57 |
+
if not (args.action_manifest_dir and args.derived_root):
|
| 58 |
+
raise ValueError("action-manifest-dir and derived-root must be supplied together")
|
| 59 |
+
for manifest in sorted(args.action_manifest_dir.glob("*.jsonl")):
|
| 60 |
+
for line in manifest.read_text().splitlines():
|
| 61 |
+
row = json.loads(line)
|
| 62 |
+
action_rows += 1
|
| 63 |
+
if "sidecar_path" not in row:
|
| 64 |
+
continue
|
| 65 |
+
target = args.derived_root / row["sidecar_path"]
|
| 66 |
+
if not target.is_file():
|
| 67 |
+
raise FileNotFoundError(target)
|
| 68 |
+
action_files += 1
|
| 69 |
+
|
| 70 |
+
print(json.dumps({
|
| 71 |
+
"status": "pass",
|
| 72 |
+
"pair_rows": len(rows),
|
| 73 |
+
"unique_stage2_frame_files": len(references),
|
| 74 |
+
"sha256_files_verified": checksum_count,
|
| 75 |
+
"action_manifest_rows": action_rows,
|
| 76 |
+
"action_sidecar_files_resolved": action_files,
|
| 77 |
+
}, indent=2))
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
if __name__ == "__main__":
|
| 81 |
+
main()
|