anhtld commited on
Commit
f19208c
·
verified ·
1 Parent(s): e4b22fd

Auto-sync: 2026-06-28 01:28:06 (part 3)

Browse files
results/paper_story_memo.md CHANGED
@@ -20,6 +20,7 @@ when queried on proposal geometry that matches those local counterfactuals.
20
  | Gradient-based field optimization does not solve the clean proposal gap | `field_optim` best observed result is 25.39% | Negative diagnostic |
21
  | A broader non-expert proposal target does not reduce the proposal gap | direct broad non-expert policy is 27.88%; with field scoring it is 26.49% | Negative diagnostic |
22
  | Counterfactual residuals transfer better than absolute retrieved actions | nearest residual retrieval is 32.12% vs absolute retrieval 28.93%; KNN4 residual drops to 29.91% | Supported as a clean bridge |
 
23
  | Seed-0 train-split field-teacher distillation does not solve the proposal gap | direct student is 26.84%; with field scoring it is 27.65% | Negative diagnostic |
24
  | All-split field-teacher distillation may still help checkpointing/coverage | allmap training has 100% train/val target coverage; rollout eval is pending | Pending |
25
 
@@ -68,7 +69,7 @@ test-time search. The cleaner novelty is:
68
 
69
  ## Active Jobs
70
 
71
- Last checked: `2026-06-28 05:20 UTC`.
72
 
73
  - `14858328`-`14858333`: completed train-split `field_selected_noexpert_bc5`;
74
  direct rollout is 26.84%, field-guided best is 27.65%.
@@ -79,6 +80,14 @@ Last checked: `2026-06-28 05:20 UTC`.
79
  - `14858451`/`14858452`: pending direct rollout evaluation and summary for allmap.
80
  - `14858453`/`14858454`: pending field-guided rollout sweep and summary for allmap.
81
  - `14858455`: rebuild `paper_table_status.*` after allmap summaries.
 
 
 
 
 
 
 
 
82
 
83
  ## Decision Rule For Field-Teacher Jobs
84
 
@@ -90,3 +99,13 @@ Last checked: `2026-06-28 05:20 UTC`.
90
  - If it fails, keep the central paper story focused on the same-state mechanism
91
  and the clean-proposal bottleneck, with residual retrieval as the strongest
92
  deployment-clean bridge.
 
 
 
 
 
 
 
 
 
 
 
20
  | Gradient-based field optimization does not solve the clean proposal gap | `field_optim` best observed result is 25.39% | Negative diagnostic |
21
  | A broader non-expert proposal target does not reduce the proposal gap | direct broad non-expert policy is 27.88%; with field scoring it is 26.49% | Negative diagnostic |
22
  | Counterfactual residuals transfer better than absolute retrieved actions | nearest residual retrieval is 32.12% vs absolute retrieval 28.93%; KNN4 residual drops to 29.91% | Supported as a clean bridge |
23
+ | Residual magnitude may be the next clean bottleneck | scale sweep for nearest residual transport is pending | Pending |
24
  | Seed-0 train-split field-teacher distillation does not solve the proposal gap | direct student is 26.84%; with field scoring it is 27.65% | Negative diagnostic |
25
  | All-split field-teacher distillation may still help checkpointing/coverage | allmap training has 100% train/val target coverage; rollout eval is pending | Pending |
26
 
 
69
 
70
  ## Active Jobs
71
 
72
+ Last checked: `2026-06-28 05:26 UTC`.
73
 
74
  - `14858328`-`14858333`: completed train-split `field_selected_noexpert_bc5`;
75
  direct rollout is 26.84%, field-guided best is 27.65%.
 
80
  - `14858451`/`14858452`: pending direct rollout evaluation and summary for allmap.
81
  - `14858453`/`14858454`: pending field-guided rollout sweep and summary for allmap.
82
  - `14858455`: rebuild `paper_table_status.*` after allmap summaries.
83
+ - `14858978`: completed CPU Apptainer unit smoke for residual-scale selection.
84
+ Earlier smoke jobs `14858889`/`14858894` caught and fixed two scale wiring bugs
85
+ before rollout jobs started.
86
+ - `14858875`/`14858876`: pending nearest residual scale `0.25` eval/summary.
87
+ - `14858877`/`14858878`: pending nearest residual scale `0.50` eval/summary.
88
+ - `14858879`/`14858880`: pending nearest residual scale `0.75` eval/summary.
89
+ - `14858881`/`14858882`: pending nearest residual scale `1.25` eval/summary.
90
+ - `14858883`: rebuild `paper_table_status.*` after residual-scale summaries.
91
 
92
  ## Decision Rule For Field-Teacher Jobs
93
 
 
99
  - If it fails, keep the central paper story focused on the same-state mechanism
100
  and the clean-proposal bottleneck, with residual retrieval as the strongest
101
  deployment-clean bridge.
102
+
103
+ ## Decision Rule For Residual-Scale Jobs
104
+
105
+ - If any residual scale beats 32.93%, promote tangent-transport residuals as the
106
+ best deployment-clean bridge.
107
+ - If a smaller scale beats 32.12% but not 32.93%, present it as evidence that
108
+ counterfactual residuals transfer as local tangent directions with a calibrated
109
+ step length.
110
+ - If all scales fail, keep scale `1.0` nearest residual retrieval as the clean
111
+ positive bridge and treat magnitude calibration as a negative ablation.
results/paper_table_status.json CHANGED
@@ -247,6 +247,120 @@
247
  "best_config": null,
248
  "gain_vs_h16_policy": 0.02376811594202899
249
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  {
251
  "key": "retrieval_residual_knn4",
252
  "label": "KNN counterfactual residual retrieval",
 
247
  "best_config": null,
248
  "gain_vs_h16_policy": 0.02376811594202899
249
  },
250
+ {
251
+ "key": "retrieval_residual_scale025",
252
+ "label": "Train-state residual retrieval, scale 0.25",
253
+ "path": "h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale0p25_summary.json",
254
+ "clean_deployment": "yes",
255
+ "same_state_proposals": "no",
256
+ "expert_proposal": "no",
257
+ "story_role": "tangent transport scale ablation",
258
+ "fallback_success": null,
259
+ "pending_job": "14858875/14858876",
260
+ "path_exists": false,
261
+ "status": "pending",
262
+ "success": null,
263
+ "std_success": null,
264
+ "completed_seeds": null,
265
+ "num_completed": null,
266
+ "best_config": null,
267
+ "gain_vs_h16_policy": null
268
+ },
269
+ {
270
+ "key": "retrieval_residual_scale050",
271
+ "label": "Train-state residual retrieval, scale 0.50",
272
+ "path": "h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale0p50_summary.json",
273
+ "clean_deployment": "yes",
274
+ "same_state_proposals": "no",
275
+ "expert_proposal": "no",
276
+ "story_role": "tangent transport scale ablation",
277
+ "fallback_success": null,
278
+ "pending_job": "14858877/14858878",
279
+ "path_exists": false,
280
+ "status": "pending",
281
+ "success": null,
282
+ "std_success": null,
283
+ "completed_seeds": null,
284
+ "num_completed": null,
285
+ "best_config": null,
286
+ "gain_vs_h16_policy": null
287
+ },
288
+ {
289
+ "key": "retrieval_residual_scale075",
290
+ "label": "Train-state residual retrieval, scale 0.75",
291
+ "path": "h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale0p75_summary.json",
292
+ "clean_deployment": "yes",
293
+ "same_state_proposals": "no",
294
+ "expert_proposal": "no",
295
+ "story_role": "tangent transport scale ablation",
296
+ "fallback_success": null,
297
+ "pending_job": "14858879/14858880",
298
+ "path_exists": false,
299
+ "status": "pending",
300
+ "success": null,
301
+ "std_success": null,
302
+ "completed_seeds": null,
303
+ "num_completed": null,
304
+ "best_config": null,
305
+ "gain_vs_h16_policy": null
306
+ },
307
+ {
308
+ "key": "retrieval_residual_scale125",
309
+ "label": "Train-state residual retrieval, scale 1.25",
310
+ "path": "h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale1p25_summary.json",
311
+ "clean_deployment": "yes",
312
+ "same_state_proposals": "no",
313
+ "expert_proposal": "no",
314
+ "story_role": "tangent transport scale ablation",
315
+ "fallback_success": null,
316
+ "pending_job": "14858881/14858882",
317
+ "path_exists": false,
318
+ "status": "pending",
319
+ "success": null,
320
+ "std_success": null,
321
+ "completed_seeds": null,
322
+ "num_completed": null,
323
+ "best_config": null,
324
+ "gain_vs_h16_policy": null
325
+ },
326
+ {
327
+ "key": "retrieval_residual_hybrid_k32",
328
+ "label": "Train-state residual + Gaussian proposals, K32 sigma0.35",
329
+ "path": "h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_hybrid_k32_sigma0p35_summary.json",
330
+ "clean_deployment": "yes",
331
+ "same_state_proposals": "no",
332
+ "expert_proposal": "no",
333
+ "story_role": "hybrid tangent/local proposal bridge",
334
+ "fallback_success": null,
335
+ "pending_job": "14859042/14859043",
336
+ "path_exists": false,
337
+ "status": "pending",
338
+ "success": null,
339
+ "std_success": null,
340
+ "completed_seeds": null,
341
+ "num_completed": null,
342
+ "best_config": null,
343
+ "gain_vs_h16_policy": null
344
+ },
345
+ {
346
+ "key": "retrieval_residual_hybrid_k64",
347
+ "label": "Train-state residual + Gaussian proposals, K64 sigma0.50",
348
+ "path": "h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_hybrid_k64_sigma0p50_summary.json",
349
+ "clean_deployment": "yes",
350
+ "same_state_proposals": "no",
351
+ "expert_proposal": "no",
352
+ "story_role": "hybrid tangent/local proposal bridge",
353
+ "fallback_success": null,
354
+ "pending_job": "14859044/14859045",
355
+ "path_exists": false,
356
+ "status": "pending",
357
+ "success": null,
358
+ "std_success": null,
359
+ "completed_seeds": null,
360
+ "num_completed": null,
361
+ "best_config": null,
362
+ "gain_vs_h16_policy": null
363
+ },
364
  {
365
  "key": "retrieval_residual_knn4",
366
  "label": "KNN counterfactual residual retrieval",
results/paper_table_status.md CHANGED
@@ -16,6 +16,12 @@ Baseline h=16 policy: 29.74%
16
  | field_selected_noexpert_policy_allmap | Field-selected no-expert distillation policy, aligned validation | pending 14858449/14858450/14858451/14858452 | pending | pending | yes | no | no | field-teacher student with aligned checkpoint selection |
17
  | field_selected_noexpert_policy_allmap_field | Field-selected no-expert distillation + field, aligned validation | pending 14858449/14858450/14858453/14858454 | pending | pending | yes | no | no | aligned field-teacher student with field scoring |
18
  | retrieval_residual | Train-state counterfactual residual retrieval | complete | 32.12% | +2.38 pp | yes | no | no | transferable local tangent proposal |
 
 
 
 
 
 
19
  | retrieval_residual_knn4 | KNN counterfactual residual retrieval | complete | 29.91% | +0.17 pp | yes | no | no | KNN tangent proposal ablation |
20
  | near_miss_only_lattice | Same-state lattice, near-miss only | complete | 55.94% | +26.20 pp | no | yes | no | minimal mechanism result |
21
  | no_expert_lattice | Same-state lattice, no expert | complete | 56.99% | +27.25 pp | no | yes | no | main conservative mechanism result |
 
16
  | field_selected_noexpert_policy_allmap | Field-selected no-expert distillation policy, aligned validation | pending 14858449/14858450/14858451/14858452 | pending | pending | yes | no | no | field-teacher student with aligned checkpoint selection |
17
  | field_selected_noexpert_policy_allmap_field | Field-selected no-expert distillation + field, aligned validation | pending 14858449/14858450/14858453/14858454 | pending | pending | yes | no | no | aligned field-teacher student with field scoring |
18
  | retrieval_residual | Train-state counterfactual residual retrieval | complete | 32.12% | +2.38 pp | yes | no | no | transferable local tangent proposal |
19
+ | retrieval_residual_scale025 | Train-state residual retrieval, scale 0.25 | pending 14858875/14858876 | pending | pending | yes | no | no | tangent transport scale ablation |
20
+ | retrieval_residual_scale050 | Train-state residual retrieval, scale 0.50 | pending 14858877/14858878 | pending | pending | yes | no | no | tangent transport scale ablation |
21
+ | retrieval_residual_scale075 | Train-state residual retrieval, scale 0.75 | pending 14858879/14858880 | pending | pending | yes | no | no | tangent transport scale ablation |
22
+ | retrieval_residual_scale125 | Train-state residual retrieval, scale 1.25 | pending 14858881/14858882 | pending | pending | yes | no | no | tangent transport scale ablation |
23
+ | retrieval_residual_hybrid_k32 | Train-state residual + Gaussian proposals, K32 sigma0.35 | pending 14859042/14859043 | pending | pending | yes | no | no | hybrid tangent/local proposal bridge |
24
+ | retrieval_residual_hybrid_k64 | Train-state residual + Gaussian proposals, K64 sigma0.50 | pending 14859044/14859045 | pending | pending | yes | no | no | hybrid tangent/local proposal bridge |
25
  | retrieval_residual_knn4 | KNN counterfactual residual retrieval | complete | 29.91% | +0.17 pp | yes | no | no | KNN tangent proposal ablation |
26
  | near_miss_only_lattice | Same-state lattice, near-miss only | complete | 55.94% | +26.20 pp | no | yes | no | minimal mechanism result |
27
  | no_expert_lattice | Same-state lattice, no expert | complete | 56.99% | +27.25 pp | no | yes | no | main conservative mechanism result |
scripts/build_paper_table_status.py CHANGED
@@ -145,6 +145,66 @@ SPECS = [
145
  story_role="transferable local tangent proposal",
146
  pending_job="14857111/14857112/14857113",
147
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  ResultSpec(
149
  key="retrieval_residual_knn4",
150
  label="KNN counterfactual residual retrieval",
 
145
  story_role="transferable local tangent proposal",
146
  pending_job="14857111/14857112/14857113",
147
  ),
148
+ ResultSpec(
149
+ key="retrieval_residual_scale025",
150
+ label="Train-state residual retrieval, scale 0.25",
151
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale0p25_summary.json",
152
+ clean_deployment="yes",
153
+ same_state_proposals="no",
154
+ expert_proposal="no",
155
+ story_role="tangent transport scale ablation",
156
+ pending_job="14858875/14858876",
157
+ ),
158
+ ResultSpec(
159
+ key="retrieval_residual_scale050",
160
+ label="Train-state residual retrieval, scale 0.50",
161
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale0p50_summary.json",
162
+ clean_deployment="yes",
163
+ same_state_proposals="no",
164
+ expert_proposal="no",
165
+ story_role="tangent transport scale ablation",
166
+ pending_job="14858877/14858878",
167
+ ),
168
+ ResultSpec(
169
+ key="retrieval_residual_scale075",
170
+ label="Train-state residual retrieval, scale 0.75",
171
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale0p75_summary.json",
172
+ clean_deployment="yes",
173
+ same_state_proposals="no",
174
+ expert_proposal="no",
175
+ story_role="tangent transport scale ablation",
176
+ pending_job="14858879/14858880",
177
+ ),
178
+ ResultSpec(
179
+ key="retrieval_residual_scale125",
180
+ label="Train-state residual retrieval, scale 1.25",
181
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_scale1p25_summary.json",
182
+ clean_deployment="yes",
183
+ same_state_proposals="no",
184
+ expert_proposal="no",
185
+ story_role="tangent transport scale ablation",
186
+ pending_job="14858881/14858882",
187
+ ),
188
+ ResultSpec(
189
+ key="retrieval_residual_hybrid_k32",
190
+ label="Train-state residual + Gaussian proposals, K32 sigma0.35",
191
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_hybrid_k32_sigma0p35_summary.json",
192
+ clean_deployment="yes",
193
+ same_state_proposals="no",
194
+ expert_proposal="no",
195
+ story_role="hybrid tangent/local proposal bridge",
196
+ pending_job="14859042/14859043",
197
+ ),
198
+ ResultSpec(
199
+ key="retrieval_residual_hybrid_k64",
200
+ label="Train-state residual + Gaussian proposals, K64 sigma0.50",
201
+ path="h16_policy_ckpt_near_miss_policy_bc5_bestpt_retrieval_residual_hybrid_k64_sigma0p50_summary.json",
202
+ clean_deployment="yes",
203
+ same_state_proposals="no",
204
+ expert_proposal="no",
205
+ story_role="hybrid tangent/local proposal bridge",
206
+ pending_job="14859044/14859045",
207
+ ),
208
  ResultSpec(
209
  key="retrieval_residual_knn4",
210
  label="KNN counterfactual residual retrieval",
scripts/eval_maniskill_policy_rollout.py CHANGED
@@ -103,6 +103,12 @@ def main(argv: list[str] | None = None) -> int:
103
  default=1,
104
  help="Nearest train states to use for retrieval_lattice/retrieval_residual proposals.",
105
  )
 
 
 
 
 
 
106
  parser.add_argument(
107
  "--lattice-exclude-types",
108
  default="",
@@ -132,6 +138,7 @@ def main(argv: list[str] | None = None) -> int:
132
  field_optim_trust_radius=args.field_optim_trust_radius,
133
  field_optim_l2_penalty=args.field_optim_l2_penalty,
134
  retrieval_neighbors=args.retrieval_neighbors,
 
135
  lattice_exclude_types=lattice_exclude_types,
136
  )
137
  print(json.dumps({key: value for key, value in result.items() if key != "rows"}, indent=2))
 
103
  default=1,
104
  help="Nearest train states to use for retrieval_lattice/retrieval_residual proposals.",
105
  )
106
+ parser.add_argument(
107
+ "--retrieval-residual-scale",
108
+ type=float,
109
+ default=1.0,
110
+ help="Scale applied to train-state residuals before adding them to the policy mean.",
111
+ )
112
  parser.add_argument(
113
  "--lattice-exclude-types",
114
  default="",
 
138
  field_optim_trust_radius=args.field_optim_trust_radius,
139
  field_optim_l2_penalty=args.field_optim_l2_penalty,
140
  retrieval_neighbors=args.retrieval_neighbors,
141
+ retrieval_residual_scale=args.retrieval_residual_scale,
142
  lattice_exclude_types=lattice_exclude_types,
143
  )
144
  print(json.dumps({key: value for key, value in result.items() if key != "rows"}, indent=2))
scripts/slurm/eval_maniskill_policy_rollout.sbatch CHANGED
@@ -49,6 +49,7 @@ 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.0}"
51
  RETRIEVAL_NEIGHBORS="${RETRIEVAL_NEIGHBORS:-1}"
 
52
  LATTICE_EXCLUDE_TYPES="${LATTICE_EXCLUDE_TYPES:-}"
53
  if [[ -n "${LATTICE_EXCLUDE_TYPES_COLON:-}" ]]; then
54
  LATTICE_EXCLUDE_TYPES="${LATTICE_EXCLUDE_TYPES_COLON//:/,}"
@@ -97,5 +98,6 @@ apptainer exec --nv \
97
  --field-optim-trust-radius "$FIELD_OPTIM_TRUST_RADIUS" \
98
  --field-optim-l2-penalty "$FIELD_OPTIM_L2_PENALTY" \
99
  --retrieval-neighbors "$RETRIEVAL_NEIGHBORS" \
 
100
  --lattice-exclude-types "$LATTICE_EXCLUDE_TYPES" \
101
  "${EXTRA_ARGS[@]}"
 
49
  FIELD_OPTIM_TRUST_RADIUS="${FIELD_OPTIM_TRUST_RADIUS:-0.5}"
50
  FIELD_OPTIM_L2_PENALTY="${FIELD_OPTIM_L2_PENALTY:-0.0}"
51
  RETRIEVAL_NEIGHBORS="${RETRIEVAL_NEIGHBORS:-1}"
52
+ RETRIEVAL_RESIDUAL_SCALE="${RETRIEVAL_RESIDUAL_SCALE:-1.0}"
53
  LATTICE_EXCLUDE_TYPES="${LATTICE_EXCLUDE_TYPES:-}"
54
  if [[ -n "${LATTICE_EXCLUDE_TYPES_COLON:-}" ]]; then
55
  LATTICE_EXCLUDE_TYPES="${LATTICE_EXCLUDE_TYPES_COLON//:/,}"
 
98
  --field-optim-trust-radius "$FIELD_OPTIM_TRUST_RADIUS" \
99
  --field-optim-l2-penalty "$FIELD_OPTIM_L2_PENALTY" \
100
  --retrieval-neighbors "$RETRIEVAL_NEIGHBORS" \
101
+ --retrieval-residual-scale "$RETRIEVAL_RESIDUAL_SCALE" \
102
  --lattice-exclude-types "$LATTICE_EXCLUDE_TYPES" \
103
  "${EXTRA_ARGS[@]}"
scripts/slurm/smoke_retrieval_residual_scale_unit.sbatch ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ #SBATCH --job-name=smoke_residual_scale
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_offset):
40
+ self.mean = mean
41
+ self.target = mean + target_offset
42
+
43
+ def forward_policy(self, observations, instructions):
44
+ del observations, instructions
45
+ return self.mean
46
+
47
+ def forward_field(self, observations, instructions, action):
48
+ del observations, instructions
49
+ distance = ((action - self.target) ** 2).reshape(action.shape[0], -1).sum(dim=1)
50
+ return {"potential": -distance}
51
+
52
+
53
+ mean = torch.full((1, 1, 3), 0.1)
54
+ residual = torch.full_like(mean, 0.8)
55
+ scale = 0.5
56
+ model = StubModel(mean, target_offset=residual * scale)
57
+ residuals = torch.stack([torch.zeros_like(mean), residual], dim=1)
58
+ actions, index = _select_action_chunk(
59
+ model,
60
+ observations=torch.zeros(1, 3),
61
+ instructions=["pick"],
62
+ torch=torch,
63
+ selection_mode="retrieval_residual",
64
+ num_candidates=1,
65
+ candidate_sigma=0.0,
66
+ selection_seed=0,
67
+ action_candidates=residuals,
68
+ retrieval_residual_scale=scale,
69
+ )
70
+ expected = mean + residual * scale
71
+ assert torch.allclose(actions, expected), (actions, expected)
72
+ assert index.tolist() == [1], index
73
+ print({"status": "ok", "scale": scale, "actions": actions.tolist(), "index": index.tolist()})
74
+ PY
scripts/slurm/summarize_h16_field_sweep.sbatch CHANGED
@@ -51,6 +51,7 @@ for result_path in sorted(run_root.glob("k*_sigma*/seed_*/online_rollout.json"))
51
  "field_optim_trust_radius": data.get("field_optim_trust_radius", 0.0),
52
  "field_optim_l2_penalty": data.get("field_optim_l2_penalty", 0.0),
53
  "retrieval_neighbors": data.get("retrieval_neighbors", 0),
 
54
  "num_groups": data.get("num_groups"),
55
  "policy_rollout_success_rate": data.get("policy_rollout_success_rate", 0.0),
56
  "policy_rollout_progress": data.get("policy_rollout_progress", 0.0),
 
51
  "field_optim_trust_radius": data.get("field_optim_trust_radius", 0.0),
52
  "field_optim_l2_penalty": data.get("field_optim_l2_penalty", 0.0),
53
  "retrieval_neighbors": data.get("retrieval_neighbors", 0),
54
+ "retrieval_residual_scale": data.get("retrieval_residual_scale", 0.0),
55
  "num_groups": data.get("num_groups"),
56
  "policy_rollout_success_rate": data.get("policy_rollout_success_rate", 0.0),
57
  "policy_rollout_progress": data.get("policy_rollout_progress", 0.0),
scripts/slurm/summarize_h16_policy_ckpt.sbatch CHANGED
@@ -60,6 +60,7 @@ for result_path in sorted(base_dir.glob(f"seed_*/{out_name}")):
60
  "field_optim_trust_radius": data.get("field_optim_trust_radius", 0.0),
61
  "field_optim_l2_penalty": data.get("field_optim_l2_penalty", 0.0),
62
  "retrieval_neighbors": data.get("retrieval_neighbors", 0),
 
63
  "policy_rollout_success_rate": data.get("policy_rollout_success_rate", 0.0),
64
  "policy_rollout_progress": data.get("policy_rollout_progress", 0.0),
65
  "oracle_success_rate": data.get("oracle_success_rate", 0.0),
@@ -120,17 +121,18 @@ lines = [
120
  f"Mean progress: {summary['mean_progress']:.2%}",
121
  f"Mean action MSE to best: {summary['mean_action_mse_to_best']:.3f}",
122
  "",
123
- "| seed | mode | k | retrieval K | sigma | opt steps | trust | success | progress | oracle | action MSE |",
124
- "|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|",
125
  ]
126
  for row in rows:
127
  lines.append(
128
- "| {seed} | {mode} | {k} | {retrieval} | {sigma:.2f} | {steps} | {trust:.2f} | "
129
  "{success:.2%} | {progress:.2%} | {oracle:.2%} | {mse:.3f} |".format(
130
  seed=row["seed"],
131
  mode=row.get("selection_mode") or "policy",
132
  k=row.get("num_candidates") or 1,
133
  retrieval=row.get("retrieval_neighbors") or 0,
 
134
  sigma=row.get("candidate_sigma") or 0.0,
135
  steps=row.get("field_optim_steps") or 0,
136
  trust=row.get("field_optim_trust_radius") or 0.0,
 
60
  "field_optim_trust_radius": data.get("field_optim_trust_radius", 0.0),
61
  "field_optim_l2_penalty": data.get("field_optim_l2_penalty", 0.0),
62
  "retrieval_neighbors": data.get("retrieval_neighbors", 0),
63
+ "retrieval_residual_scale": data.get("retrieval_residual_scale", 0.0),
64
  "policy_rollout_success_rate": data.get("policy_rollout_success_rate", 0.0),
65
  "policy_rollout_progress": data.get("policy_rollout_progress", 0.0),
66
  "oracle_success_rate": data.get("oracle_success_rate", 0.0),
 
121
  f"Mean progress: {summary['mean_progress']:.2%}",
122
  f"Mean action MSE to best: {summary['mean_action_mse_to_best']:.3f}",
123
  "",
124
+ "| seed | mode | k | retrieval K | residual scale | sigma | opt steps | trust | success | progress | oracle | action MSE |",
125
+ "|---:|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|",
126
  ]
127
  for row in rows:
128
  lines.append(
129
+ "| {seed} | {mode} | {k} | {retrieval} | {scale:.2f} | {sigma:.2f} | {steps} | {trust:.2f} | "
130
  "{success:.2%} | {progress:.2%} | {oracle:.2%} | {mse:.3f} |".format(
131
  seed=row["seed"],
132
  mode=row.get("selection_mode") or "policy",
133
  k=row.get("num_candidates") or 1,
134
  retrieval=row.get("retrieval_neighbors") or 0,
135
+ scale=row.get("retrieval_residual_scale") or 0.0,
136
  sigma=row.get("candidate_sigma") or 0.0,
137
  steps=row.get("field_optim_steps") or 0,
138
  trust=row.get("field_optim_trust_radius") or 0.0,
tests/test_maniskill_policy_rollout.py CHANGED
@@ -18,9 +18,11 @@ from dovla_cil.eval.maniskill_policy_rollout import (
18
  _RolloutCase,
19
  _adapt_action_dim,
20
  _attach_retrieved_residual_candidates,
 
21
  _load_state_archive,
22
  _numeric_action_values,
23
  _select_action_chunk,
 
24
  _summarize_rows,
25
  )
26
 
@@ -370,6 +372,63 @@ def test_retrieval_residual_mode_translates_residuals_around_policy_mean() -> No
370
  assert index.tolist() == [1]
371
 
372
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  def test_retrieval_residual_candidates_use_knn_train_residuals() -> None:
374
  def record(group_id: str, candidate_type: str, action_value: float, feature: float):
375
  return SimpleNamespace(
 
18
  _RolloutCase,
19
  _adapt_action_dim,
20
  _attach_retrieved_residual_candidates,
21
+ _effective_lattice_candidate_count,
22
  _load_state_archive,
23
  _numeric_action_values,
24
  _select_action_chunk,
25
+ _selected_candidate_type,
26
  _summarize_rows,
27
  )
28
 
 
372
  assert index.tolist() == [1]
373
 
374
 
375
+ def test_retrieval_residual_mode_scales_residuals() -> None:
376
+ import torch
377
+
378
+ mean = torch.full((1, 1, 3), 0.1)
379
+ residual = torch.full_like(mean, 0.8)
380
+ target_offset = residual * 0.5
381
+ model = _StubModel(torch, mean, best_offset=target_offset)
382
+ residuals = torch.stack([torch.zeros_like(mean), residual], dim=1)
383
+ actions, index = _select_action_chunk(
384
+ model,
385
+ observations=torch.zeros(1, 3),
386
+ instructions=["a"],
387
+ torch=torch,
388
+ selection_mode="retrieval_residual",
389
+ num_candidates=1,
390
+ candidate_sigma=0.0,
391
+ selection_seed=0,
392
+ action_candidates=residuals,
393
+ retrieval_residual_scale=0.5,
394
+ )
395
+
396
+ assert torch.allclose(actions, mean + target_offset)
397
+ assert index.tolist() == [1]
398
+
399
+
400
+ def test_retrieval_residual_gaussian_candidates_are_counted_and_labeled() -> None:
401
+ case = _RolloutCase(
402
+ group_id="g",
403
+ task_id="PickCube-v1",
404
+ source_dataset=Path("."),
405
+ state={},
406
+ observation={"features": [0.0]},
407
+ instruction="pick",
408
+ oracle_score=1.0,
409
+ oracle_success=True,
410
+ expert_score=1.0,
411
+ expert_success=True,
412
+ best_action_values=[[0.0]],
413
+ candidate_action_values=[[[0.0]], [[0.2]]],
414
+ candidate_types=["policy_residual", "residual_near_miss"],
415
+ )
416
+
417
+ assert (
418
+ _effective_lattice_candidate_count(
419
+ case,
420
+ selection_mode="retrieval_residual",
421
+ num_candidates=4,
422
+ candidate_sigma=0.2,
423
+ )
424
+ == 5
425
+ )
426
+ assert (
427
+ _selected_candidate_type(case, selected_index=4, selection_mode="retrieval_residual")
428
+ == "retrieval_residual_gaussian"
429
+ )
430
+
431
+
432
  def test_retrieval_residual_candidates_use_knn_train_residuals() -> None:
433
  def record(group_id: str, candidate_type: str, action_value: float, feature: float):
434
  return SimpleNamespace(