anhtld commited on
Commit
e5c1225
·
verified ·
1 Parent(s): 5994bfa

Auto-sync: 2026-06-27 18:32:13 (part 2)

Browse files
results/nonexpert_proposal_target_census.md ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Non-Expert Proposal Target Census
2
+
3
+ Dataset: `/scratch/knguy52/dovla/experiments/six_task_h16_collection`
4
+
5
+ This census uses the per-task `record_index.jsonl` files and defines score as
6
+ `reward_progress + 1(success)`, matching the trainer's reward score convention.
7
+
8
+ ## Candidate Counts
9
+
10
+ | candidate type | records |
11
+ |---|---:|
12
+ | expert | 2,873 |
13
+ | near_miss | 5,746 |
14
+ | wrong_direction | 2,873 |
15
+ | no_op | 2,873 |
16
+ | wrong_gripper | 2,873 |
17
+ | random_negative | 28,730 |
18
+
19
+ ## Best Candidate Per State
20
+
21
+ | selection rule | expert | near_miss | wrong_direction | wrong_gripper | random_negative | no_op |
22
+ |---|---:|---:|---:|---:|---:|---:|
23
+ | best any | 1,244 | 988 | 134 | 97 | 258 | 152 |
24
+ | best non-expert | 0 | 1,985 | 186 | 140 | 312 | 250 |
25
+ | best non-expert and successful | 0 | 1,401 | 152 | 117 | 181 | 202 |
26
+
27
+ ## Experiment Implication
28
+
29
+ The previous near-miss policy target covers the dominant useful non-expert
30
+ proposal family, but the best non-expert action is not a `near_miss` in 888 of
31
+ 2,873 states. Job `14842574` trains `nonexpert_policy_bc5` to imitate the best
32
+ non-expert local intervention using:
33
+
34
+ `POLICY_TARGET_TYPES=near_miss,wrong_direction,wrong_gripper,random_negative,no_op`
35
+
36
+ with `--loss-weight bc=5.0`. Jobs `14842575`/`14842576` evaluate and summarize
37
+ direct `best_policy.pt` rollout, while `14842577`/`14842578` evaluate and
38
+ summarize Gaussian field selection around `best.pt`.
results/paper_story_memo.md ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DoVLA-CIL Paper Story Memo
2
+
3
+ ## One-Sentence Thesis
4
+
5
+ DoVLA-CIL is a counterfactual action-selection framework: same-state intervention
6
+ lattices expose a learnable local utility field, and the field only becomes useful
7
+ when queried on proposal geometry that matches those local counterfactuals.
8
+
9
+ ## What The Current Evidence Supports
10
+
11
+ | Claim | Evidence | Status |
12
+ |---|---|---|
13
+ | Longer horizon behavior cloning is not enough | h=16 direct policy is 29.74%, essentially h=4 baseline | Supported |
14
+ | The learned field is not a generic off-manifold optimizer | Gaussian field search is 29.10% | Supported |
15
+ | Generic action libraries do not explain the gain | nearest train-state retrieval lattice is 28.93%, no-expert retrieval is 27.13% | Supported |
16
+ | Same-state local counterfactual proposals are the mechanism | near-miss-only lattice is 55.94%; removing expert+near_miss drops to 25.57% | Strongly supported |
17
+ | Conservative same-state result is large | no-expert lattice is 56.99% vs 29.74% policy | Main result |
18
+ | Full lattice gives upper result | full lattice is 69.33%, oracle is 86.78% | Strong but label expert proposal clearly |
19
+ | Deployment-clean proposal is currently a bottleneck | best clean proposal+field sweep is 32.93%, far below 56.99% | Supported |
20
+ | Gradient-based field optimization can solve the clean proposal gap | `field_optim` jobs are pending | Not yet known |
21
+ | A broader non-expert proposal target can reduce the proposal gap | `nonexpert_policy_bc5` jobs are pending; target census shows 888/2873 states have best non-expert action outside `near_miss` | Not yet known |
22
+ | Counterfactual residuals transfer better than absolute retrieved actions | `retrieval_residual` jobs are pending; absolute retrieval was 28.93% | Not yet known |
23
+
24
+ ## Main Table Candidate
25
+
26
+ Use `scripts/build_paper_table_status.py` to regenerate
27
+ `results/paper_table_status.md` after jobs finish. Until later jobs improve the
28
+ clean proposal result, the intended main rows are:
29
+
30
+ 1. Direct h=16 policy: 29.74%
31
+ 2. Gaussian field search: 29.10%
32
+ 3. Retrieval lattice, no expert: 27.13%
33
+ 4. Near-miss proposal + field, BC x5 field checkpoint: 32.93%
34
+ 5. Lattice, near-miss only: 55.94%
35
+ 6. Lattice, no expert: 56.99%
36
+ 7. Lattice, full: 69.33%
37
+ 8. Oracle ceiling: 86.78%
38
+
39
+ ## Novelty Framing
40
+
41
+ The novelty should not be framed as combining imitation learning, retrieval, and
42
+ test-time search. The cleaner novelty is:
43
+
44
+ - a data engine that measures many counterfactual interventions from the exact same
45
+ simulator state;
46
+ - a path-independent field that scores action outcomes rather than imitating one
47
+ expert action;
48
+ - a mechanism result showing that near-miss local counterfactuals are the minimal
49
+ proposal family that carries the rollout gain;
50
+ - a proposal-bottleneck story: the learned field is strong, but only on local
51
+ intervention geometry.
52
+
53
+ ## Reviewer Risks
54
+
55
+ | Risk | Current answer | Remaining work |
56
+ |---|---|---|
57
+ | Same-state lattice is not deployment-clean | show no-expert lattice and near-miss-only mechanism; show retrieval/Gaussian failures | improve clean proposal route |
58
+ | Full lattice includes expert proposal | label as upper deployment/ceiling, not main conservative result | keep no-expert row as main |
59
+ | Gains are from candidate leakage, not learning | selection never reads candidate rewards; no-expert and near-miss-only isolate mechanism | add field_optim/proposal model evidence |
60
+ | Method is just a bundle of tricks | use mechanism ablations to show one central idea: local counterfactual field | avoid presenting unrelated variants as core |
61
+ | Not SOTA enough | current clean deploy result is modest | need external baselines and stronger proposal generator before claiming SOTA |
62
+
63
+ ## Active Jobs
64
+
65
+ Last checked: `2026-06-27 21:12 UTC`.
66
+
67
+ - `14842523`: GPU smoke for `selection_mode=field_optim`.
68
+ - `14842557`: low-resource CPU unit smoke for the pure action-optimization helper.
69
+ - `14842528`: 4-config x 3-seed `field_optim` sweep, dependent on `14842523`.
70
+ - `14842529`: sweep summary, dependent on `14842528`.
71
+ - `14842551`: after-any fallback summary for partial sweep results.
72
+ - `14842574`: train `nonexpert_policy_bc5` on best non-expert local interventions.
73
+ - `14842575`: direct rollout eval for `nonexpert_policy_bc5`.
74
+ - `14842616`: direct rollout summary.
75
+ - `14842577`: field-selection sweep for `nonexpert_policy_bc5`.
76
+ - `14842617`: field-selection summary.
77
+ - `14842596`: smoke-test `retrieval_residual`, which translates nearest
78
+ train-state counterfactual residuals around the policy mean.
79
+ - `14842597`: full `retrieval_residual` rollout after smoke.
80
+ - `14842618`: `retrieval_residual` summary.
81
+ - `14842609`: smoke-test `retrieval_residual` with `RETRIEVAL_NEIGHBORS=4`.
82
+ - `14842610`: full KNN4 `retrieval_residual` rollout after smoke.
83
+ - `14842619`: KNN4 `retrieval_residual` summary.
84
+ - `14842646`: CPU unit smoke for the KNN residual helper.
85
+
86
+ Current scheduler state: `14842523` is waiting on priority, and `14842557` is
87
+ waiting for CPU nodes that are not down, drained, or reserved. The
88
+ `nonexpert_policy_bc5` train array `14842574` is waiting on unavailable GPU
89
+ nodes, and downstream jobs are waiting on dependencies.
90
+ `14842596` is also waiting on currently unavailable GPU nodes; `14842597` and
91
+ `14842618` are dependency-held.
92
+ `14842609` is waiting on the same unavailable GPU nodes; `14842610` and
93
+ `14842619` are dependency-held.
94
+ `14842646` is waiting on unavailable CPU nodes.
95
+
96
+ ## Decision Rule For Field Optim Jobs
97
+
98
+ - If `field_optim` beats 32.93% but remains below 40%, keep it as a better
99
+ deployment-clean positive control, not the main result.
100
+ - If `field_optim` reaches 40-50%, promote it to the main clean-deployment bridge
101
+ and frame same-state lattice as mechanistic supervision/upper bound.
102
+ - If `field_optim` fails or stays near 30%, keep it as a negative ablation and
103
+ prioritize training a proposal model on successful non-expert lattice candidates.
scripts/__pycache__/eval_maniskill_policy_rollout.cpython-311.pyc.139951570731952 ADDED
File without changes
scripts/build_paper_table_status.py ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ from dataclasses import asdict, dataclass
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+
10
+ RESULTS_DIR = Path("results")
11
+ BASELINE_H16_POLICY = 0.29739130434782607
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class ResultSpec:
16
+ key: str
17
+ label: str
18
+ path: str
19
+ clean_deployment: str
20
+ same_state_proposals: str
21
+ expert_proposal: str
22
+ story_role: str
23
+ fallback_success: float | None = None
24
+ pending_job: str = ""
25
+
26
+
27
+ SPECS = [
28
+ ResultSpec(
29
+ key="h16_policy",
30
+ label="Direct h=16 policy",
31
+ path="h16_policy_ckpt_summary.json",
32
+ clean_deployment="yes",
33
+ same_state_proposals="no",
34
+ expert_proposal="no",
35
+ story_role="behavior-cloning baseline",
36
+ fallback_success=0.29739130434782607,
37
+ ),
38
+ ResultSpec(
39
+ key="gaussian_field",
40
+ label="Gaussian field search",
41
+ path="h16_field_sweep_summary.json",
42
+ clean_deployment="yes",
43
+ same_state_proposals="no",
44
+ expert_proposal="no",
45
+ story_role="negative off-manifold field ablation",
46
+ fallback_success=0.2910,
47
+ ),
48
+ ResultSpec(
49
+ key="retrieval_lattice_no_expert",
50
+ label="Nearest train-state lattice, no expert",
51
+ path="h16_retrieval_lattice_no_expert_summary.json",
52
+ clean_deployment="yes",
53
+ same_state_proposals="no",
54
+ expert_proposal="no",
55
+ story_role="negative generic action-library ablation",
56
+ fallback_success=0.2713,
57
+ ),
58
+ ResultSpec(
59
+ key="near_miss_policy_bc5_field",
60
+ label="Near-miss proposal policy + field",
61
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_field_sweep_summary.json",
62
+ clean_deployment="yes",
63
+ same_state_proposals="no",
64
+ expert_proposal="no",
65
+ story_role="current best clean deployment bridge",
66
+ fallback_success=0.3293,
67
+ ),
68
+ ResultSpec(
69
+ key="field_optim",
70
+ label="Trust-region field optimization",
71
+ path="h16_field_optim_near_miss_policy_bc5_bestpt_s4_trust05_summary.json",
72
+ clean_deployment="yes",
73
+ same_state_proposals="no",
74
+ expert_proposal="no",
75
+ story_role="pending differentiable field-ascent bridge",
76
+ pending_job="14842528/14842551",
77
+ ),
78
+ ResultSpec(
79
+ key="nonexpert_policy_bc5",
80
+ label="Best non-expert proposal policy",
81
+ path="h16_policy_ckpt_nonexpert_policy_bc5_summary.json",
82
+ clean_deployment="yes",
83
+ same_state_proposals="no",
84
+ expert_proposal="no",
85
+ story_role="pending broader non-expert proposal model",
86
+ pending_job="14842574/14842575/14842616",
87
+ ),
88
+ ResultSpec(
89
+ key="nonexpert_policy_bc5_field",
90
+ label="Best non-expert proposal policy + field",
91
+ path="h16_policy_ckpt_nonexpert_policy_bc5_bestpt_field_sweep_summary.json",
92
+ clean_deployment="yes",
93
+ same_state_proposals="no",
94
+ expert_proposal="no",
95
+ story_role="pending broader proposal-field bridge",
96
+ pending_job="14842574/14842577/14842617",
97
+ ),
98
+ ResultSpec(
99
+ key="retrieval_residual",
100
+ label="Train-state counterfactual residual retrieval",
101
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_summary.json",
102
+ clean_deployment="yes",
103
+ same_state_proposals="no",
104
+ expert_proposal="no",
105
+ story_role="pending transferable local tangent proposal",
106
+ pending_job="14842596/14842597/14842618",
107
+ ),
108
+ ResultSpec(
109
+ key="retrieval_residual_knn4",
110
+ label="KNN counterfactual residual retrieval",
111
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_knn4_summary.json",
112
+ clean_deployment="yes",
113
+ same_state_proposals="no",
114
+ expert_proposal="no",
115
+ story_role="pending KNN tangent proposal",
116
+ pending_job="14842609/14842610/14842619",
117
+ ),
118
+ ResultSpec(
119
+ key="near_miss_only_lattice",
120
+ label="Same-state lattice, near-miss only",
121
+ path="h16_lattice_near_miss_only_v2_summary.json",
122
+ clean_deployment="no",
123
+ same_state_proposals="yes",
124
+ expert_proposal="no",
125
+ story_role="minimal mechanism result",
126
+ fallback_success=0.5594,
127
+ ),
128
+ ResultSpec(
129
+ key="no_expert_lattice",
130
+ label="Same-state lattice, no expert",
131
+ path="h16_lattice_no_expert_summary.json",
132
+ clean_deployment="no",
133
+ same_state_proposals="yes",
134
+ expert_proposal="no",
135
+ story_role="main conservative mechanism result",
136
+ fallback_success=0.5699,
137
+ ),
138
+ ResultSpec(
139
+ key="no_near_miss_no_expert_lattice",
140
+ label="Same-state lattice, no expert/no near-miss",
141
+ path="h16_lattice_no_near_miss_no_expert_v2_summary.json",
142
+ clean_deployment="no",
143
+ same_state_proposals="yes",
144
+ expert_proposal="no",
145
+ story_role="mechanism knockout",
146
+ fallback_success=0.2557,
147
+ ),
148
+ ResultSpec(
149
+ key="full_lattice",
150
+ label="Same-state lattice, full",
151
+ path="h16_lattice_summary.json",
152
+ clean_deployment="no",
153
+ same_state_proposals="yes",
154
+ expert_proposal="yes",
155
+ story_role="upper result with expert proposal",
156
+ fallback_success=0.6933,
157
+ ),
158
+ ]
159
+
160
+
161
+ def main() -> int:
162
+ RESULTS_DIR.mkdir(exist_ok=True)
163
+ rows = [_row_for_spec(spec) for spec in SPECS]
164
+ payload = {
165
+ "baseline_h16_policy_success": BASELINE_H16_POLICY,
166
+ "rows": rows,
167
+ "best_clean": _best_row(rows, clean="yes"),
168
+ "best_mechanism_no_expert": _best_mechanism_row(rows),
169
+ "decision_notes": _decision_notes(rows),
170
+ }
171
+ json_path = RESULTS_DIR / "paper_table_status.json"
172
+ md_path = RESULTS_DIR / "paper_table_status.md"
173
+ json_path.write_text(json.dumps(payload, indent=2) + "\n")
174
+ md_path.write_text(_render_markdown(payload) + "\n")
175
+ print(f"Wrote {json_path}")
176
+ print(f"Wrote {md_path}")
177
+ return 0
178
+
179
+
180
+ def _row_for_spec(spec: ResultSpec) -> dict[str, Any]:
181
+ path = RESULTS_DIR / spec.path
182
+ extracted = _extract_result(path) if path.exists() else {}
183
+ success = extracted.get("success", spec.fallback_success)
184
+ status = "complete" if path.exists() else ("fallback" if success is not None else "pending")
185
+ return {
186
+ **asdict(spec),
187
+ "path_exists": path.exists(),
188
+ "status": status,
189
+ "success": success,
190
+ "std_success": extracted.get("std_success"),
191
+ "completed_seeds": extracted.get("completed_seeds"),
192
+ "num_completed": extracted.get("num_completed"),
193
+ "best_config": extracted.get("best_config"),
194
+ "gain_vs_h16_policy": (success - BASELINE_H16_POLICY) if success is not None else None,
195
+ }
196
+
197
+
198
+ def _extract_result(path: Path) -> dict[str, Any]:
199
+ data = json.loads(path.read_text())
200
+ output: dict[str, Any] = {}
201
+ if "mean_success" in data:
202
+ output["success"] = _float_or_none(data.get("mean_success"))
203
+ output["std_success"] = _float_or_none(data.get("std_success"))
204
+ output["num_completed"] = data.get("num_completed")
205
+ elif isinstance(data.get("best"), dict):
206
+ best = data["best"]
207
+ output["success"] = _float_or_none(best.get("mean_success"))
208
+ output["std_success"] = _float_or_none(best.get("std_success"))
209
+ output["completed_seeds"] = best.get("completed_seeds")
210
+ output["num_completed"] = best.get("num_completed")
211
+ output["best_config"] = best.get("config")
212
+ elif "policy_rollout_success_rate" in data:
213
+ output["success"] = _float_or_none(data.get("policy_rollout_success_rate"))
214
+ output["num_completed"] = data.get("num_groups")
215
+ return output
216
+
217
+
218
+ def _float_or_none(value: Any) -> float | None:
219
+ if value is None:
220
+ return None
221
+ try:
222
+ return float(value)
223
+ except (TypeError, ValueError):
224
+ return None
225
+
226
+
227
+ def _best_row(rows: list[dict[str, Any]], *, clean: str) -> dict[str, Any] | None:
228
+ completed = [
229
+ row
230
+ for row in rows
231
+ if row["clean_deployment"] == clean and row["success"] is not None
232
+ ]
233
+ return max(completed, key=lambda row: row["success"]) if completed else None
234
+
235
+
236
+ def _best_mechanism_row(rows: list[dict[str, Any]]) -> dict[str, Any] | None:
237
+ candidates = [
238
+ row
239
+ for row in rows
240
+ if row["same_state_proposals"] == "yes"
241
+ and row["expert_proposal"] == "no"
242
+ and row["success"] is not None
243
+ ]
244
+ return max(candidates, key=lambda row: row["success"]) if candidates else None
245
+
246
+
247
+ def _decision_notes(rows: list[dict[str, Any]]) -> list[str]:
248
+ by_key = {row["key"]: row for row in rows}
249
+ notes = [
250
+ "Use no-expert same-state lattice as the conservative mechanism result, not as deployment-clean inference.",
251
+ "Use full lattice only as an upper result because it includes expert proposals.",
252
+ "Do not claim external SOTA from this table alone; add current external baselines separately.",
253
+ ]
254
+ clean_best = _best_row(rows, clean="yes")
255
+ if clean_best is not None:
256
+ notes.append(
257
+ "Current best clean deployment row is "
258
+ f"{clean_best['label']} at {_fmt_percent(clean_best['success'])}."
259
+ )
260
+ for key in ("field_optim", "retrieval_residual", "retrieval_residual_knn4"):
261
+ row = by_key[key]
262
+ if row["success"] is None:
263
+ notes.append(f"{row['label']} is pending ({row['pending_job']}).")
264
+ elif row["success"] >= 0.40:
265
+ notes.append(f"{row['label']} is strong enough to promote as a clean bridge.")
266
+ elif row["success"] > 0.3293:
267
+ notes.append(f"{row['label']} improves the clean bridge but is not yet the main result.")
268
+ else:
269
+ notes.append(f"{row['label']} should be framed as a negative/diagnostic ablation.")
270
+ return notes
271
+
272
+
273
+ def _render_markdown(payload: dict[str, Any]) -> str:
274
+ lines = [
275
+ "# Paper Table Status",
276
+ "",
277
+ f"Baseline h=16 policy: {_fmt_percent(payload['baseline_h16_policy_success'])}",
278
+ "",
279
+ "| key | method | status | success | gain vs h16 | clean | same-state props | expert prop | role |",
280
+ "|---|---|---|---:|---:|---|---|---|---|",
281
+ ]
282
+ for row in payload["rows"]:
283
+ lines.append(
284
+ "| {key} | {label} | {status} | {success} | {gain} | {clean} | {same} | {expert} | {role} |".format(
285
+ key=row["key"],
286
+ label=row["label"],
287
+ status=_status_text(row),
288
+ success=_fmt_percent(row["success"]),
289
+ gain=_fmt_signed_percent(row["gain_vs_h16_policy"]),
290
+ clean=row["clean_deployment"],
291
+ same=row["same_state_proposals"],
292
+ expert=row["expert_proposal"],
293
+ role=row["story_role"],
294
+ )
295
+ )
296
+ lines.extend(["", "## Decision Notes", ""])
297
+ for note in payload["decision_notes"]:
298
+ lines.append(f"- {note}")
299
+ return "\n".join(lines)
300
+
301
+
302
+ def _status_text(row: dict[str, Any]) -> str:
303
+ if row["status"] == "pending":
304
+ return f"pending {row['pending_job']}".strip()
305
+ if row["status"] == "fallback":
306
+ return "fallback canonical"
307
+ if row.get("best_config"):
308
+ return f"complete {row['best_config']}"
309
+ return "complete"
310
+
311
+
312
+ def _fmt_percent(value: float | None) -> str:
313
+ return "pending" if value is None else f"{100.0 * value:.2f}%"
314
+
315
+
316
+ def _fmt_signed_percent(value: float | None) -> str:
317
+ return "pending" if value is None else f"{100.0 * value:+.2f} pp"
318
+
319
+
320
+ if __name__ == "__main__":
321
+ raise SystemExit(main())
scripts/slurm/build_paper_table_status.sbatch ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ #SBATCH --job-name=build_paper_table
3
+ #SBATCH --account=def-yalda
4
+ #SBATCH --time=00:05:00
5
+ #SBATCH --cpus-per-task=1
6
+ #SBATCH --mem=1G
7
+ #SBATCH --output=outputs/hpc/logs/%x_%j.out
8
+ #SBATCH --error=outputs/hpc/logs/%x_%j.err
9
+
10
+ set -euo pipefail
11
+
12
+ PROJECT_DIR="${PROJECT_DIR:-$SLURM_SUBMIT_DIR}"
13
+ PYTHON="${PYTHON:-python3}"
14
+
15
+ cd "$PROJECT_DIR"
16
+ mkdir -p outputs/hpc/logs results
17
+
18
+ "$PYTHON" scripts/build_paper_table_status.py
scripts/slurm/eval_maniskill_policy_rollout_cpu_smoke.sbatch ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ #SBATCH --job-name=dovla_ms_cpu_smoke
3
+ #SBATCH --account=def-yalda
4
+ #SBATCH --nodes=1
5
+ #SBATCH --ntasks=1
6
+ #SBATCH --cpus-per-task=4
7
+ #SBATCH --mem=16G
8
+ #SBATCH --time=00:30:00
9
+ #SBATCH --array=0-0
10
+ #SBATCH --output=outputs/hpc/logs/%x_%A_%a.out
11
+ #SBATCH --error=outputs/hpc/logs/%x_%A_%a.err
12
+
13
+ set -euo pipefail
14
+
15
+ PROJECT_DIR="${PROJECT_DIR:-$SLURM_SUBMIT_DIR}"
16
+ DATASET="${DATASET:?Set DATASET to a ManiSkill CIL dataset or collection}"
17
+ SEED="${SLURM_ARRAY_TASK_ID:-0}"
18
+ RUN_ROOT="${RUN_ROOT:-}"
19
+ OBJECTIVE="${OBJECTIVE:-lattice_field}"
20
+ CHECKPOINT_NAME="${CHECKPOINT_NAME:-best.pt}"
21
+ OUT_NAME="${OUT_NAME:-policy_rollout_cpu_smoke.json}"
22
+ if [[ -n "$RUN_ROOT" ]]; then
23
+ CHECKPOINT="${CHECKPOINT:-$RUN_ROOT/$OBJECTIVE/seed_$SEED/$CHECKPOINT_NAME}"
24
+ OUT="${OUT:-$RUN_ROOT/$OBJECTIVE/seed_$SEED/$OUT_NAME}"
25
+ else
26
+ CHECKPOINT="${CHECKPOINT:?Set CHECKPOINT, or RUN_ROOT for seed-indexed array runs}"
27
+ OUT="${OUT:?Set OUT, or RUN_ROOT for seed-indexed array runs}"
28
+ fi
29
+
30
+ SCRATCH_ROOT="/scratch/$USER/dovla"
31
+ SIF="${SIF:-$SCRATCH_ROOT/containers/pytorch_2.7.1_cuda12.8.sif}"
32
+ PYTHON="${PYTHON:-$SCRATCH_ROOT/envs/maniskill/bin/python}"
33
+ NATIVE_LIBS="$SCRATCH_ROOT/native_libs/lib"
34
+ CPU_RENDER_LIBS="$SCRATCH_ROOT/cpu_render_libs"
35
+ CA_BUNDLE="$SCRATCH_ROOT/ca-bundle.crt"
36
+ VULKAN_ICD="$CPU_RENDER_LIBS/share/vulkan/icd.d/lvp_icd.x86_64.json"
37
+ MAX_GROUPS="${MAX_GROUPS:-8}"
38
+ GROUP_BATCH_SIZE="${GROUP_BATCH_SIZE:-2}"
39
+ SIM_BACKEND="${SIM_BACKEND:-physx_cpu}"
40
+ RENDER_BACKEND="${RENDER_BACKEND:-cpu}"
41
+ ALL_GROUPS="${ALL_GROUPS:-0}"
42
+ DEVICE="${DEVICE:-cpu}"
43
+ SELECTION_MODE="${SELECTION_MODE:-field_optim}"
44
+ NUM_CANDIDATES="${NUM_CANDIDATES:-4}"
45
+ CANDIDATE_SIGMA="${CANDIDATE_SIGMA:-0.2}"
46
+ SELECTION_SEED="${SELECTION_SEED:-0}"
47
+ FIELD_OPTIM_STEPS="${FIELD_OPTIM_STEPS:-2}"
48
+ FIELD_OPTIM_STEP_SIZE="${FIELD_OPTIM_STEP_SIZE:-0.05}"
49
+ FIELD_OPTIM_TRUST_RADIUS="${FIELD_OPTIM_TRUST_RADIUS:-0.5}"
50
+ FIELD_OPTIM_L2_PENALTY="${FIELD_OPTIM_L2_PENALTY:-0.02}"
51
+ LATTICE_EXCLUDE_TYPES="${LATTICE_EXCLUDE_TYPES:-}"
52
+ if [[ -n "${LATTICE_EXCLUDE_TYPES_COLON:-}" ]]; then
53
+ LATTICE_EXCLUDE_TYPES="${LATTICE_EXCLUDE_TYPES_COLON//:/,}"
54
+ fi
55
+
56
+ module load StdEnv/2023 apptainer/1.4.5
57
+ cd "$PROJECT_DIR"
58
+ mkdir -p outputs/hpc/logs "$(dirname "$OUT")"
59
+
60
+ RUNTIME_DIR="/tmp/$USER/dovla-policy-rollout-cpu-$SLURM_JOB_ID-${SLURM_ARRAY_TASK_ID:-0}"
61
+ CACHE_DIR="/tmp/$USER/dovla-policy-rollout-cpu-mesa-$SLURM_JOB_ID-${SLURM_ARRAY_TASK_ID:-0}"
62
+ mkdir -p "$RUNTIME_DIR" "$CACHE_DIR"
63
+ chmod 700 "$RUNTIME_DIR"
64
+
65
+ export OMP_NUM_THREADS=1
66
+ export OPENBLAS_NUM_THREADS=1
67
+ export MKL_NUM_THREADS=1
68
+ export DOVLA_TORCH_THREADS=1
69
+
70
+ EXTRA_ARGS=()
71
+ if [[ "$ALL_GROUPS" == "1" ]]; then
72
+ EXTRA_ARGS+=(--all-groups)
73
+ fi
74
+ if [[ "$MAX_GROUPS" != "all" ]]; then
75
+ EXTRA_ARGS+=(--max-groups "$MAX_GROUPS")
76
+ fi
77
+
78
+ apptainer exec \
79
+ --env "LD_LIBRARY_PATH=$CPU_RENDER_LIBS/lib:$NATIVE_LIBS,VK_ICD_FILENAMES=$VULKAN_ICD,VK_DRIVER_FILES=$VULKAN_ICD,XDG_RUNTIME_DIR=$RUNTIME_DIR,MESA_SHADER_CACHE_DIR=$CACHE_DIR,LIBGL_ALWAYS_SOFTWARE=1,LP_NUM_THREADS=1,SSL_CERT_FILE=$CA_BUNDLE,REQUESTS_CA_BUNDLE=$CA_BUNDLE,OMP_NUM_THREADS=1,OPENBLAS_NUM_THREADS=1,MKL_NUM_THREADS=1,DOVLA_TORCH_THREADS=1,MPLBACKEND=Agg,PYTHONDONTWRITEBYTECODE=1" \
80
+ -B "$PROJECT_DIR:$PROJECT_DIR" \
81
+ -B "/scratch/$USER:/scratch/$USER" \
82
+ "$SIF" "$PYTHON" scripts/eval_maniskill_policy_rollout.py \
83
+ --checkpoint "$CHECKPOINT" \
84
+ --dataset "$DATASET" \
85
+ --out "$OUT" \
86
+ --device "$DEVICE" \
87
+ --group-batch-size "$GROUP_BATCH_SIZE" \
88
+ --sim-backend "$SIM_BACKEND" \
89
+ --render-backend "$RENDER_BACKEND" \
90
+ --selection-mode "$SELECTION_MODE" \
91
+ --num-candidates "$NUM_CANDIDATES" \
92
+ --candidate-sigma "$CANDIDATE_SIGMA" \
93
+ --selection-seed "$SELECTION_SEED" \
94
+ --field-optim-steps "$FIELD_OPTIM_STEPS" \
95
+ --field-optim-step-size "$FIELD_OPTIM_STEP_SIZE" \
96
+ --field-optim-trust-radius "$FIELD_OPTIM_TRUST_RADIUS" \
97
+ --field-optim-l2-penalty "$FIELD_OPTIM_L2_PENALTY" \
98
+ --lattice-exclude-types "$LATTICE_EXCLUDE_TYPES" \
99
+ "${EXTRA_ARGS[@]}"
scripts/slurm/smoke_field_optim_unit.sbatch ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ #SBATCH --job-name=smoke_field_optim
3
+ #SBATCH --account=def-yalda
4
+ #SBATCH --nodes=1
5
+ #SBATCH --ntasks=1
6
+ #SBATCH --cpus-per-task=1
7
+ #SBATCH --mem=1G
8
+ #SBATCH --time=00:05:00
9
+ #SBATCH --output=outputs/hpc/logs/%x_%j.out
10
+ #SBATCH --error=outputs/hpc/logs/%x_%j.err
11
+
12
+ set -euo pipefail
13
+
14
+ PROJECT_DIR="${PROJECT_DIR:-$SLURM_SUBMIT_DIR}"
15
+ SCRATCH_ROOT="/scratch/$USER/dovla"
16
+ SIF="${SIF:-$SCRATCH_ROOT/containers/pytorch_2.7.1_cuda12.8.sif}"
17
+ PYTHON="${PYTHON:-$SCRATCH_ROOT/envs/maniskill/bin/python}"
18
+
19
+ module load StdEnv/2023 apptainer/1.4.5
20
+ cd "$PROJECT_DIR"
21
+ mkdir -p outputs/hpc/logs
22
+
23
+ export OMP_NUM_THREADS=1
24
+ export OPENBLAS_NUM_THREADS=1
25
+ export MKL_NUM_THREADS=1
26
+ export DOVLA_TORCH_THREADS=1
27
+
28
+ apptainer exec \
29
+ --env "OMP_NUM_THREADS=1,OPENBLAS_NUM_THREADS=1,MKL_NUM_THREADS=1,DOVLA_TORCH_THREADS=1,PYTHONDONTWRITEBYTECODE=1" \
30
+ -B "$PROJECT_DIR:$PROJECT_DIR" \
31
+ -B "/scratch/$USER:/scratch/$USER" \
32
+ "$SIF" "$PYTHON" - <<'PY'
33
+ import torch
34
+
35
+ from dovla_cil.eval.maniskill_policy_rollout import _select_action_chunk
36
+
37
+
38
+ class StubModel:
39
+ def __init__(self, mean, target):
40
+ self.mean = mean
41
+ self.target = target
42
+
43
+ def forward_policy(self, observation, instruction):
44
+ del observation, instruction
45
+ return self.mean
46
+
47
+ def forward_field(self, observation, instruction, action):
48
+ del observation, instruction
49
+ distance = ((action - self.target) ** 2).reshape(action.shape[0], -1).sum(dim=1)
50
+ return {"potential": -distance}
51
+
52
+
53
+ mean = torch.zeros(1, 1, 3)
54
+ target = torch.full_like(mean, 0.4)
55
+ model = StubModel(mean, target)
56
+ actions, index = _select_action_chunk(
57
+ model,
58
+ observations=torch.zeros(1, 3),
59
+ instructions=["smoke"],
60
+ torch=torch,
61
+ selection_mode="field_optim",
62
+ num_candidates=4,
63
+ candidate_sigma=0.2,
64
+ selection_seed=7,
65
+ field_optim_steps=6,
66
+ field_optim_step_size=0.1,
67
+ field_optim_trust_radius=0.5,
68
+ field_optim_l2_penalty=0.0,
69
+ )
70
+ before = float(((mean - target) ** 2).sum())
71
+ after = float(((actions - target) ** 2).sum())
72
+ assert after < before, (before, after, actions)
73
+ assert index.shape == (1,)
74
+
75
+ bounded_actions, _ = _select_action_chunk(
76
+ model,
77
+ observations=torch.zeros(1, 3),
78
+ instructions=["smoke"],
79
+ torch=torch,
80
+ selection_mode="field_optim",
81
+ num_candidates=4,
82
+ candidate_sigma=1.0,
83
+ selection_seed=11,
84
+ field_optim_steps=6,
85
+ field_optim_step_size=0.2,
86
+ field_optim_trust_radius=0.25,
87
+ field_optim_l2_penalty=0.0,
88
+ action_low=torch.full_like(mean, -0.5),
89
+ action_high=torch.full_like(mean, 0.5),
90
+ )
91
+ assert float(bounded_actions.max()) <= 0.250001, bounded_actions
92
+ assert float(bounded_actions.min()) >= -0.250001, bounded_actions
93
+
94
+ print(
95
+ {
96
+ "status": "ok",
97
+ "before": before,
98
+ "after": after,
99
+ "selected_index": index.tolist(),
100
+ "bounded_max": float(bounded_actions.max()),
101
+ "bounded_min": float(bounded_actions.min()),
102
+ }
103
+ )
104
+ PY
scripts/slurm/smoke_retrieval_residual_unit.sbatch ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ #SBATCH --job-name=smoke_retrieval_residual
3
+ #SBATCH --account=def-yalda
4
+ #SBATCH --nodes=1
5
+ #SBATCH --ntasks=1
6
+ #SBATCH --cpus-per-task=1
7
+ #SBATCH --mem=1G
8
+ #SBATCH --time=00:05:00
9
+ #SBATCH --output=outputs/hpc/logs/%x_%j.out
10
+ #SBATCH --error=outputs/hpc/logs/%x_%j.err
11
+
12
+ set -euo pipefail
13
+
14
+ PROJECT_DIR="${PROJECT_DIR:-$SLURM_SUBMIT_DIR}"
15
+ SCRATCH_ROOT="/scratch/$USER/dovla"
16
+ SIF="${SIF:-$SCRATCH_ROOT/containers/pytorch_2.7.1_cuda12.8.sif}"
17
+ PYTHON="${PYTHON:-$SCRATCH_ROOT/envs/maniskill/bin/python}"
18
+
19
+ module load StdEnv/2023 apptainer/1.4.5
20
+ cd "$PROJECT_DIR"
21
+ mkdir -p outputs/hpc/logs
22
+
23
+ export OMP_NUM_THREADS=1
24
+ export OPENBLAS_NUM_THREADS=1
25
+ export MKL_NUM_THREADS=1
26
+ export DOVLA_TORCH_THREADS=1
27
+
28
+ apptainer exec \
29
+ --env "OMP_NUM_THREADS=1,OPENBLAS_NUM_THREADS=1,MKL_NUM_THREADS=1,DOVLA_TORCH_THREADS=1,PYTHONDONTWRITEBYTECODE=1" \
30
+ -B "$PROJECT_DIR:$PROJECT_DIR" \
31
+ -B "/scratch/$USER:/scratch/$USER" \
32
+ "$SIF" "$PYTHON" - <<'PY'
33
+ from pathlib import Path
34
+ from types import SimpleNamespace
35
+
36
+ import numpy as np
37
+
38
+ from dovla_cil.data.schema import ActionChunk
39
+ from dovla_cil.eval.maniskill_policy_rollout import (
40
+ _RolloutCase,
41
+ _attach_retrieved_residual_candidates,
42
+ _selected_candidate_type,
43
+ )
44
+
45
+
46
+ def record(group_id: str, candidate_type: str, action_value: float, feature: float):
47
+ return SimpleNamespace(
48
+ group_id=group_id,
49
+ task_id="PickCube-v1",
50
+ candidate_type=candidate_type,
51
+ record_id=f"{group_id}-{candidate_type}-{action_value}",
52
+ observation_inline={"features": [feature, 0.0]},
53
+ action_chunk=ActionChunk(
54
+ representation="continuous",
55
+ horizon=1,
56
+ values=[[action_value, 0.0]],
57
+ ),
58
+ )
59
+
60
+
61
+ dataset = SimpleNamespace(
62
+ group_ids=["train_a", "train_b", "heldout"],
63
+ get_group=lambda group_id: {
64
+ "train_a": [
65
+ record("train_a", "expert", 1.0, 0.0),
66
+ record("train_a", "near_miss", 1.2, 0.0),
67
+ ],
68
+ "train_b": [
69
+ record("train_b", "expert", -1.0, 0.4),
70
+ record("train_b", "wrong_direction", -1.3, 0.4),
71
+ ],
72
+ "heldout": [
73
+ record("heldout", "expert", 9.0, 0.1),
74
+ record("heldout", "near_miss", 9.9, 0.1),
75
+ ],
76
+ }[group_id],
77
+ )
78
+ case = _RolloutCase(
79
+ group_id="heldout",
80
+ task_id="PickCube-v1",
81
+ source_dataset=Path("."),
82
+ state={},
83
+ observation={"features": [0.1, 0.0]},
84
+ instruction="pick",
85
+ oracle_score=1.0,
86
+ oracle_success=True,
87
+ expert_score=1.0,
88
+ expert_success=True,
89
+ best_action_values=[[9.9, 0.0]],
90
+ candidate_action_values=[],
91
+ candidate_types=[],
92
+ )
93
+
94
+ [attached] = _attach_retrieved_residual_candidates(
95
+ dataset,
96
+ [case],
97
+ heldout_group_ids=["heldout"],
98
+ obs_dim=2,
99
+ observation_mode="state",
100
+ retrieval_neighbors=2,
101
+ )
102
+
103
+ expected_values = np.asarray(
104
+ [[[0.0, 0.0]], [[0.2, 0.0]], [[0.0, 0.0]], [[-0.3, 0.0]]],
105
+ dtype=np.float32,
106
+ )
107
+ actual_values = np.asarray(attached.candidate_action_values, dtype=np.float32)
108
+ assert attached.candidate_source_group_id == "train_a;train_b"
109
+ assert attached.candidate_types == [
110
+ "policy_residual",
111
+ "residual_near_miss",
112
+ "policy_residual",
113
+ "residual_wrong_direction",
114
+ ]
115
+ assert np.allclose(actual_values, expected_values), actual_values
116
+ assert (
117
+ _selected_candidate_type(attached, selected_index=3, selection_mode="retrieval_residual")
118
+ == "retrieval_residual_residual_wrong_direction"
119
+ )
120
+ print(
121
+ {
122
+ "status": "ok",
123
+ "candidate_source_group_id": attached.candidate_source_group_id,
124
+ "candidate_types": attached.candidate_types,
125
+ "candidate_values": actual_values.tolist(),
126
+ }
127
+ )
128
+ PY