anhtld commited on
Commit
a4b2194
·
verified ·
1 Parent(s): 72ec152

Auto-sync: 2026-06-28 13:02:56

Browse files
dovla_cil/eval/maniskill_policy_rollout.py CHANGED
@@ -65,6 +65,7 @@ def evaluate_maniskill_policy_rollout(
65
  retrieval_metric: str = "raw",
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, ...] = (),
@@ -157,6 +158,8 @@ def evaluate_maniskill_policy_rollout(
157
  raise ValueError("retrieval_type_min_success must be in [0, 1]")
158
  if retrieval_residual_scale < 0:
159
  raise ValueError("retrieval_residual_scale must be non-negative")
 
 
160
  if selection_mode == "policy":
161
  num_candidates = 1
162
  checkpoint = torch.load(
@@ -250,6 +253,7 @@ def evaluate_maniskill_policy_rollout(
250
  field_optim_trust_radius=field_optim_trust_radius,
251
  field_optim_l2_penalty=field_optim_l2_penalty,
252
  retrieval_residual_scale=retrieval_residual_scale,
 
253
  lattice_exclude_types=lattice_exclude_types,
254
  )
255
  rows.extend(task_rows)
@@ -304,6 +308,9 @@ def evaluate_maniskill_policy_rollout(
304
  "retrieval_residual_scale": retrieval_residual_scale
305
  if selection_mode == "retrieval_residual"
306
  else 0.0,
 
 
 
307
  "retrieval_residual_anchor": retrieval_residual_anchor
308
  if selection_mode == "retrieval_residual"
309
  else "none",
@@ -662,6 +669,7 @@ def _evaluate_task_cases(
662
  field_optim_trust_radius: float = 0.5,
663
  field_optim_l2_penalty: float = 0.0,
664
  retrieval_residual_scale: float = 1.0,
 
665
  lattice_exclude_types: tuple[str, ...] = (),
666
  ) -> list[dict[str, Any]]:
667
  rows: list[dict[str, Any]] = []
@@ -727,6 +735,7 @@ def _evaluate_task_cases(
727
  field_optim_trust_radius=field_optim_trust_radius,
728
  field_optim_l2_penalty=field_optim_l2_penalty,
729
  retrieval_residual_scale=retrieval_residual_scale,
 
730
  action_low=action_low,
731
  action_high=action_high,
732
  action_candidates=(
@@ -796,6 +805,9 @@ def _evaluate_task_cases(
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(
@@ -804,6 +816,9 @@ def _evaluate_task_cases(
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
  }
@@ -830,6 +845,7 @@ def _select_action_chunk(
830
  field_optim_trust_radius: float = 0.5,
831
  field_optim_l2_penalty: float = 0.0,
832
  retrieval_residual_scale: float = 1.0,
 
833
  action_low: Any | None = None,
834
  action_high: Any | None = None,
835
  action_candidates: Any | None = None,
@@ -881,6 +897,7 @@ def _select_action_chunk(
881
  action_high=action_high,
882
  candidate_mask=candidate_mask,
883
  residual_scale=retrieval_residual_scale,
 
884
  num_gaussian_candidates=num_candidates,
885
  candidate_sigma=candidate_sigma,
886
  selection_seed=selection_seed,
@@ -1194,13 +1211,22 @@ def _select_residual_lattice_action_chunk(
1194
  candidate_sigma: float,
1195
  selection_seed: int,
1196
  selection_margin: float = 0.0,
 
1197
  ) -> tuple[Any, np.ndarray]:
1198
  if action_residuals.ndim != 4:
1199
  raise ValueError("action_residuals must have shape [B,K,H,D]")
1200
- candidates = policy_mean.unsqueeze(1) + float(residual_scale) * action_residuals.to(
1201
  device=policy_mean.device,
1202
  dtype=policy_mean.dtype,
1203
  )
 
 
 
 
 
 
 
 
1204
  if num_gaussian_candidates > 1 and candidate_sigma > 0:
1205
  generator = torch.Generator(device=policy_mean.device)
1206
  generator.manual_seed(int(selection_seed))
@@ -1253,15 +1279,22 @@ def _effective_lattice_candidate_count(
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
1263
 
1264
 
 
 
 
 
1265
  def _lattice_candidate_mask(
1266
  batch: list[_RolloutCase],
1267
  *,
@@ -1285,6 +1318,7 @@ def _selected_candidate_type(
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"
@@ -1293,8 +1327,10 @@ def _selected_candidate_type(
1293
  if selection_mode == "field_optim":
1294
  return "field_optim_selected"
1295
  if selection_mode == "retrieval_residual":
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:
 
65
  retrieval_metric: str = "raw",
66
  retrieval_type_min_success: float = 0.0,
67
  retrieval_residual_scale: float = 1.0,
68
+ retrieval_residual_scales: tuple[float, ...] = (),
69
  retrieval_residual_anchor: str = "expert",
70
  retrieval_residual_reduce: str = "none",
71
  lattice_exclude_types: tuple[str, ...] = (),
 
158
  raise ValueError("retrieval_type_min_success must be in [0, 1]")
159
  if retrieval_residual_scale < 0:
160
  raise ValueError("retrieval_residual_scale must be non-negative")
161
+ if any(scale < 0 for scale in retrieval_residual_scales):
162
+ raise ValueError("retrieval_residual_scales must be non-negative")
163
  if selection_mode == "policy":
164
  num_candidates = 1
165
  checkpoint = torch.load(
 
253
  field_optim_trust_radius=field_optim_trust_radius,
254
  field_optim_l2_penalty=field_optim_l2_penalty,
255
  retrieval_residual_scale=retrieval_residual_scale,
256
+ retrieval_residual_scales=retrieval_residual_scales,
257
  lattice_exclude_types=lattice_exclude_types,
258
  )
259
  rows.extend(task_rows)
 
308
  "retrieval_residual_scale": retrieval_residual_scale
309
  if selection_mode == "retrieval_residual"
310
  else 0.0,
311
+ "retrieval_residual_scales": list(retrieval_residual_scales)
312
+ if selection_mode == "retrieval_residual"
313
+ else [],
314
  "retrieval_residual_anchor": retrieval_residual_anchor
315
  if selection_mode == "retrieval_residual"
316
  else "none",
 
669
  field_optim_trust_radius: float = 0.5,
670
  field_optim_l2_penalty: float = 0.0,
671
  retrieval_residual_scale: float = 1.0,
672
+ retrieval_residual_scales: tuple[float, ...] = (),
673
  lattice_exclude_types: tuple[str, ...] = (),
674
  ) -> list[dict[str, Any]]:
675
  rows: list[dict[str, Any]] = []
 
735
  field_optim_trust_radius=field_optim_trust_radius,
736
  field_optim_l2_penalty=field_optim_l2_penalty,
737
  retrieval_residual_scale=retrieval_residual_scale,
738
+ retrieval_residual_scales=retrieval_residual_scales,
739
  action_low=action_low,
740
  action_high=action_high,
741
  action_candidates=(
 
805
  selected_index=int(candidate_index[index]),
806
  selection_mode=selection_mode,
807
  prepended_policy_candidate=prepend_policy_candidate,
808
+ residual_scale_count=_residual_scale_count(
809
+ retrieval_residual_scales
810
+ ),
811
  ),
812
  "selected_candidate_index": int(candidate_index[index]),
813
  "lattice_candidate_count": _effective_lattice_candidate_count(
 
816
  num_candidates=num_candidates,
817
  candidate_sigma=candidate_sigma,
818
  prepended_policy_candidate=prepend_policy_candidate,
819
+ residual_scale_count=_residual_scale_count(
820
+ retrieval_residual_scales
821
+ ),
822
  ),
823
  "candidate_source_group_id": case.candidate_source_group_id,
824
  }
 
845
  field_optim_trust_radius: float = 0.5,
846
  field_optim_l2_penalty: float = 0.0,
847
  retrieval_residual_scale: float = 1.0,
848
+ retrieval_residual_scales: tuple[float, ...] = (),
849
  action_low: Any | None = None,
850
  action_high: Any | None = None,
851
  action_candidates: Any | None = None,
 
897
  action_high=action_high,
898
  candidate_mask=candidate_mask,
899
  residual_scale=retrieval_residual_scale,
900
+ residual_scales=retrieval_residual_scales,
901
  num_gaussian_candidates=num_candidates,
902
  candidate_sigma=candidate_sigma,
903
  selection_seed=selection_seed,
 
1211
  candidate_sigma: float,
1212
  selection_seed: int,
1213
  selection_margin: float = 0.0,
1214
+ residual_scales: tuple[float, ...] = (),
1215
  ) -> tuple[Any, np.ndarray]:
1216
  if action_residuals.ndim != 4:
1217
  raise ValueError("action_residuals must have shape [B,K,H,D]")
1218
+ residuals = action_residuals.to(
1219
  device=policy_mean.device,
1220
  dtype=policy_mean.dtype,
1221
  )
1222
+ scales = tuple(float(scale) for scale in residual_scales) or (float(residual_scale),)
1223
+ candidate_blocks = [
1224
+ policy_mean.unsqueeze(1) + scale * residuals
1225
+ for scale in scales
1226
+ ]
1227
+ candidates = torch.cat(candidate_blocks, dim=1)
1228
+ if candidate_mask is not None and len(scales) > 1:
1229
+ candidate_mask = torch.cat([candidate_mask for _ in scales], dim=1)
1230
  if num_gaussian_candidates > 1 and candidate_sigma > 0:
1231
  generator = torch.Generator(device=policy_mean.device)
1232
  generator.manual_seed(int(selection_seed))
 
1279
  num_candidates: int,
1280
  candidate_sigma: float,
1281
  prepended_policy_candidate: bool = False,
1282
+ residual_scale_count: int = 1,
1283
  ) -> int:
1284
  count = len(case.candidate_action_values)
1285
  if prepended_policy_candidate and selection_mode in {"lattice", "retrieval_lattice"}:
1286
  count += 1
1287
+ if selection_mode == "retrieval_residual":
1288
+ count *= max(1, int(residual_scale_count))
1289
  if selection_mode == "retrieval_residual" and num_candidates > 1 and candidate_sigma > 0:
1290
  count += num_candidates - 1
1291
  return count
1292
 
1293
 
1294
+ def _residual_scale_count(residual_scales: tuple[float, ...]) -> int:
1295
+ return max(1, len(residual_scales))
1296
+
1297
+
1298
  def _lattice_candidate_mask(
1299
  batch: list[_RolloutCase],
1300
  *,
 
1318
  selected_index: int,
1319
  selection_mode: str,
1320
  prepended_policy_candidate: bool = False,
1321
+ residual_scale_count: int = 1,
1322
  ) -> str:
1323
  if selection_mode == "policy":
1324
  return "policy_continuous"
 
1327
  if selection_mode == "field_optim":
1328
  return "field_optim_selected"
1329
  if selection_mode == "retrieval_residual":
1330
+ residual_count = len(case.candidate_types)
1331
+ expanded_count = residual_count * max(1, int(residual_scale_count))
1332
+ if 0 <= selected_index < expanded_count and residual_count > 0:
1333
+ return f"retrieval_residual_{case.candidate_types[selected_index % residual_count]}"
1334
  return "retrieval_residual_gaussian"
1335
  if prepended_policy_candidate and selection_mode in {"lattice", "retrieval_lattice"}:
1336
  if selected_index == 0: