-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpolicy_loader.py
More file actions
97 lines (79 loc) · 2.98 KB
/
Copy pathpolicy_loader.py
File metadata and controls
97 lines (79 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
"""Small entry-point loader for integrating external policy repositories."""
from __future__ import annotations
import importlib
import inspect
from pathlib import Path
from chunked_policy import ChunkPredictorAdapter
from speed_policy import SpeedPolicyAdapter
from speed_observation import ObservationEncoderAdapter
def load_entrypoint(spec: str):
"""Load ``module.submodule:attribute`` without modifying ``sys.path``."""
if ":" not in spec:
raise ValueError("An entry point must use the form 'module.submodule:attribute'")
module_name, attribute_name = spec.rsplit(":", 1)
if not module_name or not attribute_name:
raise ValueError("An entry point must use the form 'module.submodule:attribute'")
module = importlib.import_module(module_name)
try:
return getattr(module, attribute_name)
except AttributeError as exc:
raise ValueError(f"{module_name!r} has no attribute {attribute_name!r}") from exc
def _call_factory(factory, available_kwargs):
if not callable(factory):
return factory
signature = inspect.signature(factory)
accepts_extra = any(
parameter.kind == inspect.Parameter.VAR_KEYWORD
for parameter in signature.parameters.values()
)
kwargs = {
name: value
for name, value in available_kwargs.items()
if accepts_extra or name in signature.parameters
}
return factory(**kwargs)
def load_chunk_predictor(
entrypoint,
task_name,
checkpoint=None,
device="cpu",
factory_kwargs=None,
):
"""Instantiate and validate an external joint-action chunk predictor.
The factory may accept any subset of ``task_name``, ``checkpoint``,
``device``, and the keys in ``factory_kwargs``. Its result must be callable
or define ``predict_chunk(observation)``.
"""
factory = load_entrypoint(entrypoint)
available = {
"task_name": task_name,
"checkpoint": None if checkpoint is None else Path(checkpoint),
"device": device,
**(factory_kwargs or {}),
}
return ChunkPredictorAdapter(_call_factory(factory, available))
def load_speed_policy(entrypoint, checkpoint=None, device="cpu", factory_kwargs=None):
"""Instantiate and validate an external physical-speed policy."""
factory = load_entrypoint(entrypoint)
available = {
"checkpoint": None if checkpoint is None else Path(checkpoint),
"device": device,
**(factory_kwargs or {}),
}
return SpeedPolicyAdapter(_call_factory(factory, available))
def load_observation_encoder(
entrypoint,
task_name,
checkpoint=None,
device="cpu",
factory_kwargs=None,
):
"""Instantiate an external speed-observation encoder."""
factory = load_entrypoint(entrypoint)
available = {
"task_name": task_name,
"checkpoint": None if checkpoint is None else Path(checkpoint),
"device": device,
**(factory_kwargs or {}),
}
return ObservationEncoderAdapter(_call_factory(factory, available))