anhtld commited on
Commit
46eadcf
·
verified ·
1 Parent(s): dd4ed55

auto-sync 2026-07-03T18:45:41Z workspace (part 3)

Browse files
workspace/scripts/eval_ctt_generated_rollout.py CHANGED
@@ -85,6 +85,25 @@ def main(argv: list[str] | None = None) -> int:
85
  "1.0 for the unscaled deployment convention."
86
  ),
87
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  parser.add_argument(
89
  "--disable-action-clipping",
90
  action="store_true",
@@ -119,6 +138,12 @@ def main(argv: list[str] | None = None) -> int:
119
  parser.error("--restore-tolerance must be positive")
120
  if args.execution_action_scale <= 0.0:
121
  parser.error("--execution-action-scale must be positive")
 
 
 
 
 
 
122
 
123
  out_dir = args.out_dir
124
  out_dir.mkdir(parents=True, exist_ok=True)
@@ -226,6 +251,8 @@ def main(argv: list[str] | None = None) -> int:
226
  restore_tolerance=args.restore_tolerance,
227
  clip_actions=not args.disable_action_clipping,
228
  execution_action_scale=args.execution_action_scale,
 
 
229
  log_path=log_path,
230
  )
231
  _append_log(log_path, f"rollout complete rows={len(rows)}")
@@ -251,6 +278,12 @@ def main(argv: list[str] | None = None) -> int:
251
  "lossless": False,
252
  "delta_scale": args.delta_scale,
253
  "execution_action_scale": args.execution_action_scale,
 
 
 
 
 
 
254
  "action_clipping_enabled": not args.disable_action_clipping,
255
  },
256
  "rows": rows,
@@ -541,6 +574,8 @@ def rollout_generated_cases(
541
  restore_tolerance: float,
542
  clip_actions: bool,
543
  execution_action_scale: float = 1.0,
 
 
544
  log_path: Path | None = None,
545
  ) -> list[dict[str, Any]]:
546
  archives: dict[Path, dict[str, Any]] = {}
@@ -582,6 +617,8 @@ def rollout_generated_cases(
582
  restore_tolerance=restore_tolerance,
583
  clip_actions=clip_actions,
584
  execution_action_scale=execution_action_scale,
 
 
585
  log_path=log_path,
586
  )
587
  )
@@ -612,14 +649,21 @@ def rollout_generated_cases(
612
  action_groups.append(np.stack(group_actions, axis=0))
613
  candidate_values = np.stack(action_groups, axis=0).astype(np.float32)
614
  candidate_values = _adapt_action_dim_4d(candidate_values, env_dim)
615
- candidate_values = _scale_actions_4d(candidate_values, execution_action_scale)
 
 
 
 
 
 
616
  safety = _action_bound_diagnostics_4d(candidate_values, env)
617
  if clip_actions:
618
  candidate_values = _clip_to_action_space_4d(candidate_values, env)
619
  _append_log(
620
  log_path,
621
  f"execute task={task_id} start={start} shape={candidate_values.shape} "
622
- f"clip_actions={clip_actions} execution_action_scale={execution_action_scale}",
 
623
  )
624
  _after_state, rewards, successes, restore_error = execute_grouped_action_lattice_batch(
625
  base_env,
@@ -662,6 +706,8 @@ def rollout_generated_cases(
662
  ),
663
  restore_error=float(restore_error),
664
  execution_action_scale=execution_action_scale,
 
 
665
  )
666
  )
667
  finally:
@@ -682,6 +728,8 @@ def _rollout_cpu_sequential_batch(
682
  restore_tolerance: float,
683
  clip_actions: bool,
684
  execution_action_scale: float,
 
 
685
  log_path: Path | None,
686
  ) -> list[dict[str, Any]]:
687
  rows: list[dict[str, Any]] = []
@@ -711,7 +759,13 @@ def _rollout_cpu_sequential_batch(
711
  1, 1, *action.shape
712
  )
713
  candidate_values = _adapt_action_dim_4d(candidate_values, env_dim)
714
- candidate_values = _scale_actions_4d(candidate_values, execution_action_scale)
 
 
 
 
 
 
715
  safety = _action_bound_diagnostics_4d(candidate_values, env)
716
  if clip_actions:
717
  candidate_values = _clip_to_action_space_4d(candidate_values, env)
@@ -719,7 +773,8 @@ def _rollout_cpu_sequential_batch(
719
  log_path,
720
  f"execute sequential task={task_id} chart={target.chart_id} "
721
  f"candidate={candidate_index} shape={candidate_values.shape} "
722
- f"clip_actions={clip_actions} execution_action_scale={execution_action_scale}",
 
723
  )
724
  _after_state, rewards, successes, restore_error = execute_grouped_action_lattice_batch(
725
  base_env,
@@ -749,6 +804,8 @@ def _rollout_cpu_sequential_batch(
749
  action_clip_max_abs=action_clip_max_abs,
750
  restore_error=max(restore_errors, default=0.0),
751
  execution_action_scale=execution_action_scale,
 
 
752
  )
753
  )
754
  finally:
@@ -768,6 +825,8 @@ def _measured_row_from_rollout(
768
  action_clip_max_abs: list[float | None] | None = None,
769
  restore_error: float,
770
  execution_action_scale: float = 1.0,
 
 
771
  ) -> dict[str, Any]:
772
  if safety_violations is None:
773
  safety_violations = [None] * len(utilities)
@@ -789,6 +848,12 @@ def _measured_row_from_rollout(
789
  "instruction": target.instruction,
790
  "candidates_evaluated": True,
791
  "execution_action_scale": float(execution_action_scale),
 
 
 
 
 
 
792
  "selected_index": 0,
793
  "base_utility": base_utility,
794
  "stored_base_utility": target.stored_base_utility,
@@ -917,12 +982,72 @@ def _adapt_action_dim_4d(actions: np.ndarray, action_dim: int) -> np.ndarray:
917
  return np.concatenate([actions.astype(np.float32, copy=False), pad], axis=-1)
918
 
919
 
920
- def _scale_actions_4d(actions: np.ndarray, scale: float) -> np.ndarray:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
921
  if not math.isfinite(float(scale)) or float(scale) <= 0.0:
922
  raise ValueError("execution action scale must be positive and finite")
923
- if float(scale) == 1.0:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
924
  return actions.astype(np.float32, copy=False)
925
- return (actions.astype(np.float32, copy=False) * float(scale)).astype(np.float32, copy=False)
 
 
 
 
 
 
 
 
 
926
 
927
 
928
  def _clip_to_action_space_4d(actions: np.ndarray, env: Any) -> np.ndarray:
 
85
  "1.0 for the unscaled deployment convention."
86
  ),
87
  )
88
+ parser.add_argument(
89
+ "--execution-action-scale-vector",
90
+ default="",
91
+ help=(
92
+ "Optional comma-separated per-action-dimension positive scale vector "
93
+ "applied after --execution-action-scale and before the execution "
94
+ "transform. This diagnoses dimension-wise action representation mismatch."
95
+ ),
96
+ )
97
+ parser.add_argument(
98
+ "--execution-action-transform",
99
+ choices=("identity", "tanh"),
100
+ default="identity",
101
+ help=(
102
+ "Action-convention transform applied before action-bound diagnostics, "
103
+ "optional clipping, and simulator execution. 'identity' preserves "
104
+ "decoded controls; 'tanh' smoothly maps controls into finite env bounds."
105
+ ),
106
+ )
107
  parser.add_argument(
108
  "--disable-action-clipping",
109
  action="store_true",
 
138
  parser.error("--restore-tolerance must be positive")
139
  if args.execution_action_scale <= 0.0:
140
  parser.error("--execution-action-scale must be positive")
141
+ try:
142
+ execution_action_scale_vector = _parse_execution_action_scale_vector(
143
+ args.execution_action_scale_vector
144
+ )
145
+ except ValueError as exc:
146
+ parser.error(str(exc))
147
 
148
  out_dir = args.out_dir
149
  out_dir.mkdir(parents=True, exist_ok=True)
 
251
  restore_tolerance=args.restore_tolerance,
252
  clip_actions=not args.disable_action_clipping,
253
  execution_action_scale=args.execution_action_scale,
254
+ execution_action_scale_vector=execution_action_scale_vector,
255
+ execution_action_transform=args.execution_action_transform,
256
  log_path=log_path,
257
  )
258
  _append_log(log_path, f"rollout complete rows={len(rows)}")
 
278
  "lossless": False,
279
  "delta_scale": args.delta_scale,
280
  "execution_action_scale": args.execution_action_scale,
281
+ "execution_action_scale_vector": (
282
+ None
283
+ if execution_action_scale_vector is None
284
+ else execution_action_scale_vector.astype(float).tolist()
285
+ ),
286
+ "execution_action_transform": args.execution_action_transform,
287
  "action_clipping_enabled": not args.disable_action_clipping,
288
  },
289
  "rows": rows,
 
574
  restore_tolerance: float,
575
  clip_actions: bool,
576
  execution_action_scale: float = 1.0,
577
+ execution_action_scale_vector: np.ndarray | None = None,
578
+ execution_action_transform: str = "identity",
579
  log_path: Path | None = None,
580
  ) -> list[dict[str, Any]]:
581
  archives: dict[Path, dict[str, Any]] = {}
 
617
  restore_tolerance=restore_tolerance,
618
  clip_actions=clip_actions,
619
  execution_action_scale=execution_action_scale,
620
+ execution_action_scale_vector=execution_action_scale_vector,
621
+ execution_action_transform=execution_action_transform,
622
  log_path=log_path,
623
  )
624
  )
 
649
  action_groups.append(np.stack(group_actions, axis=0))
650
  candidate_values = np.stack(action_groups, axis=0).astype(np.float32)
651
  candidate_values = _adapt_action_dim_4d(candidate_values, env_dim)
652
+ candidate_values = _prepare_actions_for_execution_4d(
653
+ candidate_values,
654
+ env,
655
+ execution_action_scale=execution_action_scale,
656
+ execution_action_scale_vector=execution_action_scale_vector,
657
+ execution_action_transform=execution_action_transform,
658
+ )
659
  safety = _action_bound_diagnostics_4d(candidate_values, env)
660
  if clip_actions:
661
  candidate_values = _clip_to_action_space_4d(candidate_values, env)
662
  _append_log(
663
  log_path,
664
  f"execute task={task_id} start={start} shape={candidate_values.shape} "
665
+ f"clip_actions={clip_actions} execution_action_scale={execution_action_scale} "
666
+ f"execution_action_transform={execution_action_transform}",
667
  )
668
  _after_state, rewards, successes, restore_error = execute_grouped_action_lattice_batch(
669
  base_env,
 
706
  ),
707
  restore_error=float(restore_error),
708
  execution_action_scale=execution_action_scale,
709
+ execution_action_scale_vector=execution_action_scale_vector,
710
+ execution_action_transform=execution_action_transform,
711
  )
712
  )
713
  finally:
 
728
  restore_tolerance: float,
729
  clip_actions: bool,
730
  execution_action_scale: float,
731
+ execution_action_scale_vector: np.ndarray | None,
732
+ execution_action_transform: str,
733
  log_path: Path | None,
734
  ) -> list[dict[str, Any]]:
735
  rows: list[dict[str, Any]] = []
 
759
  1, 1, *action.shape
760
  )
761
  candidate_values = _adapt_action_dim_4d(candidate_values, env_dim)
762
+ candidate_values = _prepare_actions_for_execution_4d(
763
+ candidate_values,
764
+ env,
765
+ execution_action_scale=execution_action_scale,
766
+ execution_action_scale_vector=execution_action_scale_vector,
767
+ execution_action_transform=execution_action_transform,
768
+ )
769
  safety = _action_bound_diagnostics_4d(candidate_values, env)
770
  if clip_actions:
771
  candidate_values = _clip_to_action_space_4d(candidate_values, env)
 
773
  log_path,
774
  f"execute sequential task={task_id} chart={target.chart_id} "
775
  f"candidate={candidate_index} shape={candidate_values.shape} "
776
+ f"clip_actions={clip_actions} execution_action_scale={execution_action_scale} "
777
+ f"execution_action_transform={execution_action_transform}",
778
  )
779
  _after_state, rewards, successes, restore_error = execute_grouped_action_lattice_batch(
780
  base_env,
 
804
  action_clip_max_abs=action_clip_max_abs,
805
  restore_error=max(restore_errors, default=0.0),
806
  execution_action_scale=execution_action_scale,
807
+ execution_action_scale_vector=execution_action_scale_vector,
808
+ execution_action_transform=execution_action_transform,
809
  )
810
  )
811
  finally:
 
825
  action_clip_max_abs: list[float | None] | None = None,
826
  restore_error: float,
827
  execution_action_scale: float = 1.0,
828
+ execution_action_scale_vector: np.ndarray | None = None,
829
+ execution_action_transform: str = "identity",
830
  ) -> dict[str, Any]:
831
  if safety_violations is None:
832
  safety_violations = [None] * len(utilities)
 
848
  "instruction": target.instruction,
849
  "candidates_evaluated": True,
850
  "execution_action_scale": float(execution_action_scale),
851
+ "execution_action_scale_vector": (
852
+ None
853
+ if execution_action_scale_vector is None
854
+ else execution_action_scale_vector.astype(float).tolist()
855
+ ),
856
+ "execution_action_transform": str(execution_action_transform),
857
  "selected_index": 0,
858
  "base_utility": base_utility,
859
  "stored_base_utility": target.stored_base_utility,
 
982
  return np.concatenate([actions.astype(np.float32, copy=False), pad], axis=-1)
983
 
984
 
985
+ def _parse_execution_action_scale_vector(raw: str) -> np.ndarray | None:
986
+ text = str(raw or "").strip()
987
+ if not text:
988
+ return None
989
+ values = [float(item.strip()) for item in text.split(",") if item.strip()]
990
+ if not values:
991
+ return None
992
+ vector = np.asarray(values, dtype=np.float32)
993
+ if np.any(~np.isfinite(vector)) or np.any(vector <= 0.0):
994
+ raise ValueError("--execution-action-scale-vector values must be positive and finite")
995
+ return vector
996
+
997
+
998
+ def _prepare_actions_for_execution_4d(
999
+ actions: np.ndarray,
1000
+ env: Any,
1001
+ *,
1002
+ execution_action_scale: float,
1003
+ execution_action_scale_vector: np.ndarray | None,
1004
+ execution_action_transform: str,
1005
+ ) -> np.ndarray:
1006
+ scaled = _scale_actions_4d(
1007
+ actions,
1008
+ execution_action_scale,
1009
+ scale_vector=execution_action_scale_vector,
1010
+ )
1011
+ return _transform_actions_4d(scaled, env, execution_action_transform)
1012
+
1013
+
1014
+ def _scale_actions_4d(
1015
+ actions: np.ndarray,
1016
+ scale: float,
1017
+ *,
1018
+ scale_vector: np.ndarray | None = None,
1019
+ ) -> np.ndarray:
1020
  if not math.isfinite(float(scale)) or float(scale) <= 0.0:
1021
  raise ValueError("execution action scale must be positive and finite")
1022
+ output = actions.astype(np.float32, copy=False)
1023
+ if float(scale) != 1.0:
1024
+ output = output * float(scale)
1025
+ if scale_vector is not None:
1026
+ vector = np.asarray(scale_vector, dtype=np.float32).reshape(-1)
1027
+ if vector.size != output.shape[-1]:
1028
+ raise ValueError(
1029
+ "execution action scale vector length must match adapted action dimension"
1030
+ )
1031
+ if np.any(~np.isfinite(vector)) or np.any(vector <= 0.0):
1032
+ raise ValueError("execution action scale vector must be positive and finite")
1033
+ output = output * vector.reshape(1, 1, 1, -1)
1034
+ return output.astype(np.float32, copy=False)
1035
+
1036
+
1037
+ def _transform_actions_4d(actions: np.ndarray, env: Any, transform: str) -> np.ndarray:
1038
+ value = str(transform or "identity").strip().lower()
1039
+ if value == "identity":
1040
  return actions.astype(np.float32, copy=False)
1041
+ if value != "tanh":
1042
+ raise ValueError(f"Unknown execution action transform: {transform}")
1043
+ squashed = np.tanh(actions.astype(np.float32, copy=False))
1044
+ bounds = _action_space_bounds(actions, env)
1045
+ if bounds is None:
1046
+ return squashed.astype(np.float32, copy=False)
1047
+ low_arr, high_arr = bounds
1048
+ center = ((low_arr + high_arr) * 0.5).reshape(1, 1, 1, -1)
1049
+ half_range = ((high_arr - low_arr) * 0.5).reshape(1, 1, 1, -1)
1050
+ return (center + half_range * squashed).astype(np.float32, copy=False)
1051
 
1052
 
1053
  def _clip_to_action_space_4d(actions: np.ndarray, env: Any) -> np.ndarray:
workspace/scripts/slurm/eval_ctt_generated_rollout.sbatch CHANGED
@@ -37,6 +37,8 @@ RENDER_BACKEND="${RENDER_BACKEND:-cpu}"
37
  RESTORE_TOLERANCE="${RESTORE_TOLERANCE:-1e-5}"
38
  DELTA_SCALE="${DELTA_SCALE:-1.0}"
39
  EXECUTION_ACTION_SCALE="${EXECUTION_ACTION_SCALE:-1.0}"
 
 
40
  BOOTSTRAP_SAMPLES="${BOOTSTRAP_SAMPLES:-200}"
41
  INCLUDE_TARGETS_WITHOUT_POSITIVES="${INCLUDE_TARGETS_WITHOUT_POSITIVES:-0}"
42
  EXCLUDE_SELF_SOURCE="${EXCLUDE_SELF_SOURCE:-0}"
@@ -91,5 +93,7 @@ apptainer exec \
91
  --restore-tolerance "$RESTORE_TOLERANCE" \
92
  --delta-scale "$DELTA_SCALE" \
93
  --execution-action-scale "$EXECUTION_ACTION_SCALE" \
 
 
94
  --bootstrap-samples "$BOOTSTRAP_SAMPLES" \
95
  "${EXTRA_ARGS[@]}"
 
37
  RESTORE_TOLERANCE="${RESTORE_TOLERANCE:-1e-5}"
38
  DELTA_SCALE="${DELTA_SCALE:-1.0}"
39
  EXECUTION_ACTION_SCALE="${EXECUTION_ACTION_SCALE:-1.0}"
40
+ EXECUTION_ACTION_SCALE_VECTOR="${EXECUTION_ACTION_SCALE_VECTOR:-}"
41
+ EXECUTION_ACTION_TRANSFORM="${EXECUTION_ACTION_TRANSFORM:-identity}"
42
  BOOTSTRAP_SAMPLES="${BOOTSTRAP_SAMPLES:-200}"
43
  INCLUDE_TARGETS_WITHOUT_POSITIVES="${INCLUDE_TARGETS_WITHOUT_POSITIVES:-0}"
44
  EXCLUDE_SELF_SOURCE="${EXCLUDE_SELF_SOURCE:-0}"
 
93
  --restore-tolerance "$RESTORE_TOLERANCE" \
94
  --delta-scale "$DELTA_SCALE" \
95
  --execution-action-scale "$EXECUTION_ACTION_SCALE" \
96
+ --execution-action-scale-vector "$EXECUTION_ACTION_SCALE_VECTOR" \
97
+ --execution-action-transform "$EXECUTION_ACTION_TRANSFORM" \
98
  --bootstrap-samples "$BOOTSTRAP_SAMPLES" \
99
  "${EXTRA_ARGS[@]}"