anhtld commited on
Commit
b3666b2
·
verified ·
1 Parent(s): e7ae80e

Auto-sync: 2026-06-28 07:13:10

Browse files
Files changed (1) hide show
  1. dovla_cil/training/trainer.py +87 -12
dovla_cil/training/trainer.py CHANGED
@@ -117,11 +117,14 @@ class DoVLATrainer:
117
  self.output_dir = ensure_dir(config.output_dir)
118
  self.dataset = CILDataset(config.dataset_dir)
119
  self.policy_target_record_ids = _load_policy_target_map(config.policy_target_map)
 
 
 
120
  self.train_group_ids, self.val_group_ids = _split_group_ids(
121
  self.dataset.group_ids, val_fraction=config.val_fraction, seed=config.seed
122
  )
123
  self.policy_target_map_coverage = _policy_target_map_coverage(
124
- self.policy_target_record_ids,
125
  train_group_ids=self.train_group_ids,
126
  val_group_ids=self.val_group_ids,
127
  )
@@ -168,7 +171,7 @@ class DoVLATrainer:
168
 
169
  def train(self) -> dict[str, Any]:
170
  write_json(self._resolved_config(), self.output_dir / "resolved_config.json")
171
- if self.policy_target_record_ids:
172
  coverage = self.policy_target_map_coverage
173
  print(
174
  "policy_target_map_coverage "
@@ -292,13 +295,8 @@ class DoVLATrainer:
292
  pred_reward, [record.group_id for record in records]
293
  )
294
 
295
- best_records = _best_records_by_group(
296
- records,
297
- candidate_types=self.config.policy_target_types,
298
- target_record_ids=self.policy_target_record_ids,
299
- )
300
  best_obs = self._obs_tensor(best_records)
301
- best_actions = self._action_tensor(best_records)
302
  best_instructions = [record.instruction for record in best_records]
303
  pred_best_actions = self.model.forward_policy(best_obs, best_instructions)
304
 
@@ -362,6 +360,50 @@ class DoVLATrainer:
362
  )
363
  return total, metrics
364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  def _rank_loss(self, pred_reward, target_reward, pair_indices: list[tuple[int, int]]):
366
  assert torch is not None
367
  if not pair_indices:
@@ -743,18 +785,51 @@ def _load_policy_target_map(path: str | Path | None) -> dict[str, str]:
743
  return output
744
 
745
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
746
  def _policy_target_map_coverage(
747
- target_record_ids: dict[str, str],
748
  *,
749
  train_group_ids: list[str],
750
  val_group_ids: list[str],
751
  ) -> dict[str, float | int]:
752
- train_covered = sum(1 for group_id in train_group_ids if group_id in target_record_ids)
753
- val_covered = sum(1 for group_id in val_group_ids if group_id in target_record_ids)
 
754
  train_groups = len(train_group_ids)
755
  val_groups = len(val_group_ids)
756
  return {
757
- "num_targets": len(target_record_ids),
758
  "train_groups": train_groups,
759
  "train_covered": train_covered,
760
  "train_coverage": train_covered / train_groups if train_groups else 0.0,
 
117
  self.output_dir = ensure_dir(config.output_dir)
118
  self.dataset = CILDataset(config.dataset_dir)
119
  self.policy_target_record_ids = _load_policy_target_map(config.policy_target_map)
120
+ self.policy_target_action_values = _load_policy_target_action_map(
121
+ config.policy_target_map
122
+ )
123
  self.train_group_ids, self.val_group_ids = _split_group_ids(
124
  self.dataset.group_ids, val_fraction=config.val_fraction, seed=config.seed
125
  )
126
  self.policy_target_map_coverage = _policy_target_map_coverage(
127
+ set(self.policy_target_record_ids) | set(self.policy_target_action_values),
128
  train_group_ids=self.train_group_ids,
129
  val_group_ids=self.val_group_ids,
130
  )
 
171
 
172
  def train(self) -> dict[str, Any]:
173
  write_json(self._resolved_config(), self.output_dir / "resolved_config.json")
174
+ if self.policy_target_record_ids or self.policy_target_action_values:
175
  coverage = self.policy_target_map_coverage
176
  print(
177
  "policy_target_map_coverage "
 
295
  pred_reward, [record.group_id for record in records]
296
  )
297
 
298
+ best_records, best_actions = self._policy_bc_targets(records)
 
 
 
 
299
  best_obs = self._obs_tensor(best_records)
 
300
  best_instructions = [record.instruction for record in best_records]
301
  pred_best_actions = self.model.forward_policy(best_obs, best_instructions)
302
 
 
360
  )
361
  return total, metrics
362
 
363
+ def _policy_bc_targets(self, records: list[CILRecord]) -> tuple[list[CILRecord], Any]:
364
+ assert torch is not None
365
+ target_records: list[CILRecord] = []
366
+ target_values: list[list[list[float]]] = []
367
+ used_group_ids: set[str] = set()
368
+ grouped: dict[str, list[CILRecord]] = {}
369
+ for record in records:
370
+ grouped.setdefault(record.group_id, []).append(record)
371
+
372
+ for group_id, group_records in grouped.items():
373
+ mapped_action = self.policy_target_action_values.get(group_id)
374
+ if mapped_action is None:
375
+ continue
376
+ target_records.append(group_records[0])
377
+ target_values.append(
378
+ _coerce_policy_target_action(
379
+ mapped_action,
380
+ action_dim=self.config.action_dim,
381
+ action_horizon=self.config.action_horizon,
382
+ )
383
+ )
384
+ used_group_ids.add(group_id)
385
+
386
+ fallback_records = _best_records_by_group(
387
+ [record for record in records if record.group_id not in used_group_ids],
388
+ candidate_types=self.config.policy_target_types,
389
+ target_record_ids=self.policy_target_record_ids,
390
+ )
391
+ for record in fallback_records:
392
+ target_records.append(record)
393
+ target_values.append(
394
+ vectorize_toy_action(
395
+ record.action_chunk,
396
+ action_dim=self.config.action_dim,
397
+ action_horizon=self.config.action_horizon,
398
+ )
399
+ )
400
+ best_actions = torch.tensor(
401
+ target_values,
402
+ dtype=torch.float32,
403
+ device=self.device,
404
+ )
405
+ return target_records, best_actions
406
+
407
  def _rank_loss(self, pred_reward, target_reward, pair_indices: list[tuple[int, int]]):
408
  assert torch is not None
409
  if not pair_indices:
 
785
  return output
786
 
787
 
788
+ def _load_policy_target_action_map(path: str | Path | None) -> dict[str, list[list[float]]]:
789
+ if path is None:
790
+ return {}
791
+ payload = json.loads(Path(path).read_text())
792
+ raw_targets = payload.get("targets", payload)
793
+ output: dict[str, list[list[float]]] = {}
794
+ for group_id, value in raw_targets.items():
795
+ if not isinstance(value, dict):
796
+ continue
797
+ raw_action = value.get("action_values", value.get("action"))
798
+ if raw_action is None:
799
+ continue
800
+ output[str(group_id)] = [
801
+ [float(item) for item in row]
802
+ for row in raw_action
803
+ ]
804
+ return output
805
+
806
+
807
+ def _coerce_policy_target_action(
808
+ action_values: list[list[float]],
809
+ *,
810
+ action_dim: int,
811
+ action_horizon: int,
812
+ ) -> list[list[float]]:
813
+ return vectorize_toy_action(
814
+ action_values,
815
+ action_dim=action_dim,
816
+ action_horizon=action_horizon,
817
+ )
818
+
819
+
820
  def _policy_target_map_coverage(
821
+ target_group_ids: set[str] | dict[str, Any],
822
  *,
823
  train_group_ids: list[str],
824
  val_group_ids: list[str],
825
  ) -> dict[str, float | int]:
826
+ target_groups = set(target_group_ids)
827
+ train_covered = sum(1 for group_id in train_group_ids if group_id in target_groups)
828
+ val_covered = sum(1 for group_id in val_group_ids if group_id in target_groups)
829
  train_groups = len(train_group_ids)
830
  val_groups = len(val_group_ids)
831
  return {
832
+ "num_targets": len(target_groups),
833
  "train_groups": train_groups,
834
  "train_covered": train_covered,
835
  "train_coverage": train_covered / train_groups if train_groups else 0.0,