Auto-sync: 2026-06-27 10:19:52
Browse files
dovla_cil/eval/maniskill_policy_rollout.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
| 2 |
|
| 3 |
import pickle
|
| 4 |
from collections import Counter, defaultdict
|
| 5 |
-
from dataclasses import dataclass
|
| 6 |
from pathlib import Path
|
| 7 |
from typing import Any
|
| 8 |
|
|
@@ -37,6 +37,7 @@ class _RolloutCase:
|
|
| 37 |
best_action_values: list[list[float]]
|
| 38 |
candidate_action_values: list[list[list[float]]]
|
| 39 |
candidate_types: list[str]
|
|
|
|
| 40 |
|
| 41 |
|
| 42 |
def evaluate_maniskill_policy_rollout(
|
|
@@ -74,6 +75,11 @@ def evaluate_maniskill_policy_rollout(
|
|
| 74 |
When ``selection_mode == 'lattice'`` the evaluator scores the pre-generated CIL action
|
| 75 |
lattice for the current state with the learned field and executes the selected action. It
|
| 76 |
never reads candidate rewards during selection; it only uses the action proposals.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
"""
|
| 78 |
|
| 79 |
try:
|
|
@@ -88,8 +94,10 @@ def evaluate_maniskill_policy_rollout(
|
|
| 88 |
|
| 89 |
if group_batch_size <= 0:
|
| 90 |
raise ValueError("group_batch_size must be positive")
|
| 91 |
-
if selection_mode not in {"policy", "field", "lattice"}:
|
| 92 |
-
raise ValueError(
|
|
|
|
|
|
|
| 93 |
if num_candidates <= 0:
|
| 94 |
raise ValueError("num_candidates must be positive")
|
| 95 |
if selection_mode == "policy":
|
|
@@ -125,6 +133,14 @@ def evaluate_maniskill_policy_rollout(
|
|
| 125 |
group_ids,
|
| 126 |
observation_mode=model_config.observation_mode,
|
| 127 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
by_task: dict[str, list[_RolloutCase]] = defaultdict(list)
|
| 129 |
for case in cases:
|
| 130 |
by_task[case.task_id].append(case)
|
|
@@ -154,7 +170,7 @@ def evaluate_maniskill_policy_rollout(
|
|
| 154 |
task_summaries[task_id] = _summarize_rows(task_rows)
|
| 155 |
|
| 156 |
effective_num_candidates = num_candidates
|
| 157 |
-
if selection_mode
|
| 158 |
effective_num_candidates = max(
|
| 159 |
[int(row.get("lattice_candidate_count", 0)) for row in rows],
|
| 160 |
default=0,
|
|
@@ -335,6 +351,7 @@ def _evaluate_task_cases(
|
|
| 335 |
device=device,
|
| 336 |
)
|
| 337 |
if selection_mode == "lattice"
|
|
|
|
| 338 |
else None
|
| 339 |
),
|
| 340 |
candidate_mask=(
|
|
@@ -344,7 +361,8 @@ def _evaluate_task_cases(
|
|
| 344 |
device=device,
|
| 345 |
exclude_types=lattice_exclude_types,
|
| 346 |
)
|
| 347 |
-
if selection_mode
|
|
|
|
| 348 |
else None
|
| 349 |
),
|
| 350 |
)
|
|
@@ -394,6 +412,7 @@ def _evaluate_task_cases(
|
|
| 394 |
),
|
| 395 |
"selected_candidate_index": int(candidate_index[index]),
|
| 396 |
"lattice_candidate_count": len(case.candidate_action_values),
|
|
|
|
| 397 |
}
|
| 398 |
)
|
| 399 |
finally:
|
|
@@ -424,9 +443,9 @@ def _select_action_chunk(
|
|
| 424 |
scored, so no dataset candidate ever leaks into the deployed action.
|
| 425 |
"""
|
| 426 |
|
| 427 |
-
if selection_mode
|
| 428 |
if action_candidates is None:
|
| 429 |
-
raise ValueError("
|
| 430 |
return _select_lattice_action_chunk(
|
| 431 |
model,
|
| 432 |
observations,
|
|
|
|
| 2 |
|
| 3 |
import pickle
|
| 4 |
from collections import Counter, defaultdict
|
| 5 |
+
from dataclasses import dataclass, replace
|
| 6 |
from pathlib import Path
|
| 7 |
from typing import Any
|
| 8 |
|
|
|
|
| 37 |
best_action_values: list[list[float]]
|
| 38 |
candidate_action_values: list[list[list[float]]]
|
| 39 |
candidate_types: list[str]
|
| 40 |
+
candidate_source_group_id: str | None = None
|
| 41 |
|
| 42 |
|
| 43 |
def evaluate_maniskill_policy_rollout(
|
|
|
|
| 75 |
When ``selection_mode == 'lattice'`` the evaluator scores the pre-generated CIL action
|
| 76 |
lattice for the current state with the learned field and executes the selected action. It
|
| 77 |
never reads candidate rewards during selection; it only uses the action proposals.
|
| 78 |
+
|
| 79 |
+
When ``selection_mode == 'retrieval_lattice'`` action proposals come from the nearest
|
| 80 |
+
training-split state with the same task rather than the evaluated state's own lattice. This
|
| 81 |
+
tests whether the field can use reusable intervention proposals without same-state proposal
|
| 82 |
+
leakage.
|
| 83 |
"""
|
| 84 |
|
| 85 |
try:
|
|
|
|
| 94 |
|
| 95 |
if group_batch_size <= 0:
|
| 96 |
raise ValueError("group_batch_size must be positive")
|
| 97 |
+
if selection_mode not in {"policy", "field", "lattice", "retrieval_lattice"}:
|
| 98 |
+
raise ValueError(
|
| 99 |
+
"selection_mode must be 'policy', 'field', 'lattice', or 'retrieval_lattice'"
|
| 100 |
+
)
|
| 101 |
if num_candidates <= 0:
|
| 102 |
raise ValueError("num_candidates must be positive")
|
| 103 |
if selection_mode == "policy":
|
|
|
|
| 133 |
group_ids,
|
| 134 |
observation_mode=model_config.observation_mode,
|
| 135 |
)
|
| 136 |
+
if selection_mode == "retrieval_lattice":
|
| 137 |
+
cases = _attach_retrieved_lattice_candidates(
|
| 138 |
+
dataset,
|
| 139 |
+
cases,
|
| 140 |
+
eval_group_ids=group_ids,
|
| 141 |
+
obs_dim=model_config.obs_dim,
|
| 142 |
+
observation_mode=model_config.observation_mode,
|
| 143 |
+
)
|
| 144 |
by_task: dict[str, list[_RolloutCase]] = defaultdict(list)
|
| 145 |
for case in cases:
|
| 146 |
by_task[case.task_id].append(case)
|
|
|
|
| 170 |
task_summaries[task_id] = _summarize_rows(task_rows)
|
| 171 |
|
| 172 |
effective_num_candidates = num_candidates
|
| 173 |
+
if selection_mode in {"lattice", "retrieval_lattice"}:
|
| 174 |
effective_num_candidates = max(
|
| 175 |
[int(row.get("lattice_candidate_count", 0)) for row in rows],
|
| 176 |
default=0,
|
|
|
|
| 351 |
device=device,
|
| 352 |
)
|
| 353 |
if selection_mode == "lattice"
|
| 354 |
+
or selection_mode == "retrieval_lattice"
|
| 355 |
else None
|
| 356 |
),
|
| 357 |
candidate_mask=(
|
|
|
|
| 361 |
device=device,
|
| 362 |
exclude_types=lattice_exclude_types,
|
| 363 |
)
|
| 364 |
+
if selection_mode in {"lattice", "retrieval_lattice"}
|
| 365 |
+
and lattice_exclude_types
|
| 366 |
else None
|
| 367 |
),
|
| 368 |
)
|
|
|
|
| 412 |
),
|
| 413 |
"selected_candidate_index": int(candidate_index[index]),
|
| 414 |
"lattice_candidate_count": len(case.candidate_action_values),
|
| 415 |
+
"candidate_source_group_id": case.candidate_source_group_id,
|
| 416 |
}
|
| 417 |
)
|
| 418 |
finally:
|
|
|
|
| 443 |
scored, so no dataset candidate ever leaks into the deployed action.
|
| 444 |
"""
|
| 445 |
|
| 446 |
+
if selection_mode in {"lattice", "retrieval_lattice"}:
|
| 447 |
if action_candidates is None:
|
| 448 |
+
raise ValueError(f"{selection_mode} selection requires action_candidates")
|
| 449 |
return _select_lattice_action_chunk(
|
| 450 |
model,
|
| 451 |
observations,
|