anhtld commited on
Commit
3959bea
·
verified ·
1 Parent(s): e99ddea

Auto-sync: 2026-06-28 12:31:29

Browse files
dovla_cil/eval/maniskill_policy_rollout.py CHANGED
@@ -56,6 +56,7 @@ def evaluate_maniskill_policy_rollout(
56
  candidate_sigma: float = 0.2,
57
  selection_seed: int = 0,
58
  selection_margin: float = 0.0,
 
59
  field_optim_steps: int = 0,
60
  field_optim_step_size: float = 0.05,
61
  field_optim_trust_radius: float = 0.5,
@@ -65,6 +66,7 @@ def evaluate_maniskill_policy_rollout(
65
  retrieval_type_min_success: float = 0.0,
66
  retrieval_residual_scale: float = 1.0,
67
  retrieval_residual_anchor: str = "expert",
 
68
  lattice_exclude_types: tuple[str, ...] = (),
69
  ) -> dict[str, Any]:
70
  """Execute a checkpoint policy from restored ManiSkill CIL states.
@@ -147,6 +149,10 @@ def evaluate_maniskill_policy_rollout(
147
  raise ValueError("retrieval_metric must be 'raw' or 'zscore'")
148
  if retrieval_residual_anchor not in {"expert", "policy"}:
149
  raise ValueError("retrieval_residual_anchor must be 'expert' or 'policy'")
 
 
 
 
150
  if not 0.0 <= retrieval_type_min_success <= 1.0:
151
  raise ValueError("retrieval_type_min_success must be in [0, 1]")
152
  if retrieval_residual_scale < 0:
@@ -212,6 +218,7 @@ def evaluate_maniskill_policy_rollout(
212
  retrieval_metric=retrieval_metric,
213
  retrieval_type_min_success=retrieval_type_min_success,
214
  retrieval_residual_anchor=retrieval_residual_anchor,
 
215
  )
216
  by_task: dict[str, list[_RolloutCase]] = defaultdict(list)
217
  for case in cases:
@@ -237,6 +244,7 @@ def evaluate_maniskill_policy_rollout(
237
  candidate_sigma=candidate_sigma,
238
  selection_seed=selection_seed,
239
  selection_margin=selection_margin,
 
240
  field_optim_steps=field_optim_steps,
241
  field_optim_step_size=field_optim_step_size,
242
  field_optim_trust_radius=field_optim_trust_radius,
@@ -271,6 +279,7 @@ def evaluate_maniskill_policy_rollout(
271
  and num_candidates > 1
272
  else 0.0,
273
  "selection_margin": selection_margin,
 
274
  "field_optim_steps": field_optim_steps
275
  if selection_mode == "field_optim"
276
  else 0,
@@ -298,6 +307,9 @@ def evaluate_maniskill_policy_rollout(
298
  "retrieval_residual_anchor": retrieval_residual_anchor
299
  if selection_mode == "retrieval_residual"
300
  else "none",
 
 
 
301
  "lattice_exclude_types": list(lattice_exclude_types),
302
  "policy_rollout_success_rate": _mean([row["success"] for row in rows]),
303
  "policy_rollout_progress": _mean([row["progress"] for row in rows]),
@@ -460,6 +472,7 @@ def _attach_retrieved_residual_candidates(
460
  retrieval_metric: str = "raw",
461
  retrieval_type_min_success: float = 0.0,
462
  retrieval_residual_anchor: str = "expert",
 
463
  ) -> list[_RolloutCase]:
464
  if observation_mode != "state":
465
  raise ValueError("retrieval_residual currently supports state observations only")
@@ -532,6 +545,12 @@ def _attach_retrieved_residual_candidates(
532
  source_group_ids.append(source_group_id)
533
  residuals.extend(source_residuals)
534
  candidate_types.extend(source_candidate_types)
 
 
 
 
 
 
535
  output.append(
536
  replace(
537
  case,
@@ -543,6 +562,38 @@ def _attach_retrieved_residual_candidates(
543
  return output
544
 
545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  def _candidate_type_success_rates(
547
  dataset: CILDataset,
548
  *,
@@ -605,6 +656,7 @@ def _evaluate_task_cases(
605
  candidate_sigma: float = 0.2,
606
  selection_seed: int = 0,
607
  selection_margin: float = 0.0,
 
608
  field_optim_steps: int = 0,
609
  field_optim_step_size: float = 0.05,
610
  field_optim_trust_radius: float = 0.5,
@@ -669,6 +721,7 @@ def _evaluate_task_cases(
669
  candidate_sigma=candidate_sigma,
670
  selection_seed=selection_seed + start,
671
  selection_margin=selection_margin,
 
672
  field_optim_steps=field_optim_steps,
673
  field_optim_step_size=field_optim_step_size,
674
  field_optim_trust_radius=field_optim_trust_radius,
@@ -742,6 +795,7 @@ def _evaluate_task_cases(
742
  case,
743
  selected_index=int(candidate_index[index]),
744
  selection_mode=selection_mode,
 
745
  ),
746
  "selected_candidate_index": int(candidate_index[index]),
747
  "lattice_candidate_count": _effective_lattice_candidate_count(
@@ -749,6 +803,7 @@ def _evaluate_task_cases(
749
  selection_mode=selection_mode,
750
  num_candidates=num_candidates,
751
  candidate_sigma=candidate_sigma,
 
752
  ),
753
  "candidate_source_group_id": case.candidate_source_group_id,
754
  }
@@ -769,6 +824,7 @@ def _select_action_chunk(
769
  candidate_sigma: float,
770
  selection_seed: int,
771
  selection_margin: float = 0.0,
 
772
  field_optim_steps: int = 0,
773
  field_optim_step_size: float = 0.05,
774
  field_optim_trust_radius: float = 0.5,
@@ -793,6 +849,9 @@ def _select_action_chunk(
793
  if selection_mode in {"lattice", "retrieval_lattice"}:
794
  if action_candidates is None:
795
  raise ValueError(f"{selection_mode} selection requires action_candidates")
 
 
 
796
  return _select_lattice_action_chunk(
797
  model,
798
  observations,
@@ -803,6 +862,7 @@ def _select_action_chunk(
803
  action_high=action_high,
804
  candidate_mask=candidate_mask,
805
  selection_margin=selection_margin,
 
806
  )
807
 
808
  policy_mean = model.forward_policy(observations, instructions)
@@ -1065,9 +1125,25 @@ def _select_lattice_action_chunk(
1065
  action_high: Any | None,
1066
  candidate_mask: Any | None,
1067
  selection_margin: float = 0.0,
 
1068
  ) -> tuple[Any, np.ndarray]:
1069
  if action_candidates.ndim != 4:
1070
  raise ValueError("action_candidates must have shape [B,K,H,D]")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1071
  batch_size, candidate_count = action_candidates.shape[:2]
1072
  candidates = _clamp_action_tensor(
1073
  action_candidates,
@@ -1176,8 +1252,11 @@ def _effective_lattice_candidate_count(
1176
  selection_mode: str,
1177
  num_candidates: int,
1178
  candidate_sigma: float,
 
1179
  ) -> int:
1180
  count = len(case.candidate_action_values)
 
 
1181
  if selection_mode == "retrieval_residual" and num_candidates > 1 and candidate_sigma > 0:
1182
  count += num_candidates - 1
1183
  return count
@@ -1205,6 +1284,7 @@ def _selected_candidate_type(
1205
  *,
1206
  selected_index: int,
1207
  selection_mode: str,
 
1208
  ) -> str:
1209
  if selection_mode == "policy":
1210
  return "policy_continuous"
@@ -1216,6 +1296,10 @@ def _selected_candidate_type(
1216
  if 0 <= selected_index < len(case.candidate_types):
1217
  return f"retrieval_residual_{case.candidate_types[selected_index]}"
1218
  return "retrieval_residual_gaussian"
 
 
 
 
1219
  if 0 <= selected_index < len(case.candidate_types):
1220
  return f"lattice_{case.candidate_types[selected_index]}"
1221
  return "lattice_unknown"
 
56
  candidate_sigma: float = 0.2,
57
  selection_seed: int = 0,
58
  selection_margin: float = 0.0,
59
+ prepend_policy_candidate: bool = False,
60
  field_optim_steps: int = 0,
61
  field_optim_step_size: float = 0.05,
62
  field_optim_trust_radius: float = 0.5,
 
66
  retrieval_type_min_success: float = 0.0,
67
  retrieval_residual_scale: float = 1.0,
68
  retrieval_residual_anchor: str = "expert",
69
+ retrieval_residual_reduce: str = "none",
70
  lattice_exclude_types: tuple[str, ...] = (),
71
  ) -> dict[str, Any]:
72
  """Execute a checkpoint policy from restored ManiSkill CIL states.
 
149
  raise ValueError("retrieval_metric must be 'raw' or 'zscore'")
150
  if retrieval_residual_anchor not in {"expert", "policy"}:
151
  raise ValueError("retrieval_residual_anchor must be 'expert' or 'policy'")
152
+ if retrieval_residual_reduce not in {"none", "mean_by_type", "median_by_type"}:
153
+ raise ValueError(
154
+ "retrieval_residual_reduce must be 'none', 'mean_by_type', or 'median_by_type'"
155
+ )
156
  if not 0.0 <= retrieval_type_min_success <= 1.0:
157
  raise ValueError("retrieval_type_min_success must be in [0, 1]")
158
  if retrieval_residual_scale < 0:
 
218
  retrieval_metric=retrieval_metric,
219
  retrieval_type_min_success=retrieval_type_min_success,
220
  retrieval_residual_anchor=retrieval_residual_anchor,
221
+ retrieval_residual_reduce=retrieval_residual_reduce,
222
  )
223
  by_task: dict[str, list[_RolloutCase]] = defaultdict(list)
224
  for case in cases:
 
244
  candidate_sigma=candidate_sigma,
245
  selection_seed=selection_seed,
246
  selection_margin=selection_margin,
247
+ prepend_policy_candidate=prepend_policy_candidate,
248
  field_optim_steps=field_optim_steps,
249
  field_optim_step_size=field_optim_step_size,
250
  field_optim_trust_radius=field_optim_trust_radius,
 
279
  and num_candidates > 1
280
  else 0.0,
281
  "selection_margin": selection_margin,
282
+ "prepend_policy_candidate": bool(prepend_policy_candidate),
283
  "field_optim_steps": field_optim_steps
284
  if selection_mode == "field_optim"
285
  else 0,
 
307
  "retrieval_residual_anchor": retrieval_residual_anchor
308
  if selection_mode == "retrieval_residual"
309
  else "none",
310
+ "retrieval_residual_reduce": retrieval_residual_reduce
311
+ if selection_mode == "retrieval_residual"
312
+ else "none",
313
  "lattice_exclude_types": list(lattice_exclude_types),
314
  "policy_rollout_success_rate": _mean([row["success"] for row in rows]),
315
  "policy_rollout_progress": _mean([row["progress"] for row in rows]),
 
472
  retrieval_metric: str = "raw",
473
  retrieval_type_min_success: float = 0.0,
474
  retrieval_residual_anchor: str = "expert",
475
+ retrieval_residual_reduce: str = "none",
476
  ) -> list[_RolloutCase]:
477
  if observation_mode != "state":
478
  raise ValueError("retrieval_residual currently supports state observations only")
 
545
  source_group_ids.append(source_group_id)
546
  residuals.extend(source_residuals)
547
  candidate_types.extend(source_candidate_types)
548
+ if retrieval_residual_reduce != "none":
549
+ residuals, candidate_types = _reduce_residual_candidates_by_type(
550
+ residuals,
551
+ candidate_types,
552
+ mode=retrieval_residual_reduce,
553
+ )
554
  output.append(
555
  replace(
556
  case,
 
562
  return output
563
 
564
 
565
+ def _reduce_residual_candidates_by_type(
566
+ residuals: list[list[list[float]]],
567
+ candidate_types: list[str],
568
+ *,
569
+ mode: str,
570
+ ) -> tuple[list[list[list[float]]], list[str]]:
571
+ if mode not in {"mean_by_type", "median_by_type"}:
572
+ raise ValueError("mode must be 'mean_by_type' or 'median_by_type'")
573
+ if len(residuals) != len(candidate_types):
574
+ raise ValueError("residuals and candidate_types must have the same length")
575
+
576
+ ordered_types = list(dict.fromkeys(candidate_types))
577
+ reduced_residuals: list[list[list[float]]] = []
578
+ reduced_types: list[str] = []
579
+ for candidate_type in ordered_types:
580
+ values = [
581
+ np.asarray(residual, dtype=np.float32)
582
+ for residual, residual_type in zip(residuals, candidate_types)
583
+ if residual_type == candidate_type
584
+ ]
585
+ if not values:
586
+ continue
587
+ stack = np.stack(values, axis=0)
588
+ if mode == "mean_by_type":
589
+ reduced = np.mean(stack, axis=0)
590
+ else:
591
+ reduced = np.median(stack, axis=0)
592
+ reduced_residuals.append(reduced.astype(np.float32).tolist())
593
+ reduced_types.append(candidate_type)
594
+ return reduced_residuals, reduced_types
595
+
596
+
597
  def _candidate_type_success_rates(
598
  dataset: CILDataset,
599
  *,
 
656
  candidate_sigma: float = 0.2,
657
  selection_seed: int = 0,
658
  selection_margin: float = 0.0,
659
+ prepend_policy_candidate: bool = False,
660
  field_optim_steps: int = 0,
661
  field_optim_step_size: float = 0.05,
662
  field_optim_trust_radius: float = 0.5,
 
721
  candidate_sigma=candidate_sigma,
722
  selection_seed=selection_seed + start,
723
  selection_margin=selection_margin,
724
+ prepend_policy_candidate=prepend_policy_candidate,
725
  field_optim_steps=field_optim_steps,
726
  field_optim_step_size=field_optim_step_size,
727
  field_optim_trust_radius=field_optim_trust_radius,
 
795
  case,
796
  selected_index=int(candidate_index[index]),
797
  selection_mode=selection_mode,
798
+ prepended_policy_candidate=prepend_policy_candidate,
799
  ),
800
  "selected_candidate_index": int(candidate_index[index]),
801
  "lattice_candidate_count": _effective_lattice_candidate_count(
 
803
  selection_mode=selection_mode,
804
  num_candidates=num_candidates,
805
  candidate_sigma=candidate_sigma,
806
+ prepended_policy_candidate=prepend_policy_candidate,
807
  ),
808
  "candidate_source_group_id": case.candidate_source_group_id,
809
  }
 
824
  candidate_sigma: float,
825
  selection_seed: int,
826
  selection_margin: float = 0.0,
827
+ prepend_policy_candidate: bool = False,
828
  field_optim_steps: int = 0,
829
  field_optim_step_size: float = 0.05,
830
  field_optim_trust_radius: float = 0.5,
 
849
  if selection_mode in {"lattice", "retrieval_lattice"}:
850
  if action_candidates is None:
851
  raise ValueError(f"{selection_mode} selection requires action_candidates")
852
+ policy_baseline = None
853
+ if prepend_policy_candidate:
854
+ policy_baseline = model.forward_policy(observations, instructions)
855
  return _select_lattice_action_chunk(
856
  model,
857
  observations,
 
862
  action_high=action_high,
863
  candidate_mask=candidate_mask,
864
  selection_margin=selection_margin,
865
+ baseline_action=policy_baseline,
866
  )
867
 
868
  policy_mean = model.forward_policy(observations, instructions)
 
1125
  action_high: Any | None,
1126
  candidate_mask: Any | None,
1127
  selection_margin: float = 0.0,
1128
+ baseline_action: Any | None = None,
1129
  ) -> tuple[Any, np.ndarray]:
1130
  if action_candidates.ndim != 4:
1131
  raise ValueError("action_candidates must have shape [B,K,H,D]")
1132
+ if baseline_action is not None:
1133
+ if baseline_action.ndim != 3:
1134
+ raise ValueError("baseline_action must have shape [B,H,D]")
1135
+ action_candidates = torch.cat(
1136
+ [baseline_action.unsqueeze(1), action_candidates],
1137
+ dim=1,
1138
+ )
1139
+ if candidate_mask is not None:
1140
+ baseline_mask = torch.ones(
1141
+ candidate_mask.shape[0],
1142
+ 1,
1143
+ dtype=candidate_mask.dtype,
1144
+ device=candidate_mask.device,
1145
+ )
1146
+ candidate_mask = torch.cat([baseline_mask, candidate_mask], dim=1)
1147
  batch_size, candidate_count = action_candidates.shape[:2]
1148
  candidates = _clamp_action_tensor(
1149
  action_candidates,
 
1252
  selection_mode: str,
1253
  num_candidates: int,
1254
  candidate_sigma: float,
1255
+ prepended_policy_candidate: bool = False,
1256
  ) -> int:
1257
  count = len(case.candidate_action_values)
1258
+ if prepended_policy_candidate and selection_mode in {"lattice", "retrieval_lattice"}:
1259
+ count += 1
1260
  if selection_mode == "retrieval_residual" and num_candidates > 1 and candidate_sigma > 0:
1261
  count += num_candidates - 1
1262
  return count
 
1284
  *,
1285
  selected_index: int,
1286
  selection_mode: str,
1287
+ prepended_policy_candidate: bool = False,
1288
  ) -> str:
1289
  if selection_mode == "policy":
1290
  return "policy_continuous"
 
1296
  if 0 <= selected_index < len(case.candidate_types):
1297
  return f"retrieval_residual_{case.candidate_types[selected_index]}"
1298
  return "retrieval_residual_gaussian"
1299
+ if prepended_policy_candidate and selection_mode in {"lattice", "retrieval_lattice"}:
1300
+ if selected_index == 0:
1301
+ return "policy_continuous"
1302
+ selected_index -= 1
1303
  if 0 <= selected_index < len(case.candidate_types):
1304
  return f"lattice_{case.candidate_types[selected_index]}"
1305
  return "lattice_unknown"
logs/auto_sync_hf.log CHANGED
@@ -197,3 +197,4 @@ No files have been modified since last commit. Skipping to prevent empty commit.
197
  No files have been modified since last commit. Skipping to prevent empty commit.
198
  No files have been modified since last commit. Skipping to prevent empty commit.
199
  No files have been modified since last commit. Skipping to prevent empty commit.
 
 
197
  No files have been modified since last commit. Skipping to prevent empty commit.
198
  No files have been modified since last commit. Skipping to prevent empty commit.
199
  No files have been modified since last commit. Skipping to prevent empty commit.
200
+ No files have been modified since last commit. Skipping to prevent empty commit.