amesa-train-dev 0.20.5.dev13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- amesa_train_dev-0.20.5.dev13/PKG-INFO +53 -0
- amesa_train_dev-0.20.5.dev13/README.md +27 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/__init__.py +7 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/actor/__init__.py +5 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/actor/actor.py +164 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/actor/metrics_actor.py +137 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/actor/sim_mgr_actor.py +42 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/config/__init__.py +12 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/config/env_config.py +23 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/config/step_info.py +52 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/env/__init__.py +7 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/env/env.py +566 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/env/env_mgr.py +103 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/env/env_multi_agent.py +120 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/env_processors/__init__.py +3 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/evaluation/__init__.py +5 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/evaluation/evaluate.py +469 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/examples/__init__.py +0 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/examples/actor_counter.py +70 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/examples/actor_counter_nested.py +25 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/main.py +13 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/model/__init__.py +3 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/model/skill_model.py +132 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/model/skill_model_coordinated.py +126 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/networking/__init__.py +0 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/networking/episode_manager.py +839 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/__init__.py +56 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/skill_controller_processor.py +155 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/skill_coordinated_population_processor.py +267 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/skill_coordinated_set_processor.py +261 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/skill_processor.py +455 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/skill_processor_base.py +203 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/skill_selector_controller_processor.py +125 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/skill_processors/skill_selector_processor.py +222 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/__init__.py +15 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/algorithm_config.py +21 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/amesa_ppo.py +191 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/create_skill_trainer.py +29 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/skill_trainer.py +196 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/skill_trainer_base.py +692 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/skill_trainer_coordinated_population.py +206 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/skill_trainer_coordinated_set.py +199 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/trainer.py +880 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/trainer/training_callbacks.py +116 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/utils/__init__.py +16 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/utils/env_validator.py +173 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/utils/onnx_helper.py +141 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/utils/space_utils.py +294 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/utils/validate_util.py +202 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/v2/__init__.py +12 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/v2/controller_component.py +172 -0
- amesa_train_dev-0.20.5.dev13/amesa_train/v2/skill_processor_component.py +607 -0
- amesa_train_dev-0.20.5.dev13/amesa_train_dev.egg-info/PKG-INFO +53 -0
- amesa_train_dev-0.20.5.dev13/amesa_train_dev.egg-info/SOURCES.txt +108 -0
- amesa_train_dev-0.20.5.dev13/amesa_train_dev.egg-info/dependency_links.txt +1 -0
- amesa_train_dev-0.20.5.dev13/amesa_train_dev.egg-info/requires.txt +15 -0
- amesa_train_dev-0.20.5.dev13/amesa_train_dev.egg-info/top_level.txt +1 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/__init__.c +4923 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/actor/__init__.c +4889 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/actor/actor.c +12092 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/actor/metrics_actor.c +11019 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/actor/sim_mgr_actor.c +9055 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/config/__init__.c +4962 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/config/env_config.c +9106 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/config/step_info.c +9075 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/env/__init__.c +4950 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/env/env.c +28017 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/env/env_mgr.c +9645 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/env/env_multi_agent.c +13623 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/env_processors/__init__.c +4591 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/evaluation/__init__.c +4899 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/evaluation/evaluate.c +20844 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/examples/__init__.c +4589 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/examples/actor_counter.c +15373 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/examples/actor_counter_nested.c +8972 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/main.c +7160 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/model/__init__.c +4591 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/model/skill_model.c +12271 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/model/skill_model_coordinated.c +11821 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/networking/__init__.c +4589 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/networking/episode_manager.c +39070 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/__init__.c +11370 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/skill_controller_processor.c +16210 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/skill_coordinated_population_processor.c +18903 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/skill_coordinated_set_processor.c +18518 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/skill_processor.c +21553 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/skill_processor_base.c +17411 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/skill_selector_controller_processor.c +14804 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/skill_processors/skill_selector_processor.c +17801 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/__init__.c +5110 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/algorithm_config.c +8718 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/amesa_ppo.c +12078 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/create_skill_trainer.c +8593 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/skill_trainer.c +12854 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/skill_trainer_base.c +20302 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/skill_trainer_coordinated_population.c +13621 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/skill_trainer_coordinated_set.c +13149 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/trainer.c +32665 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/trainer/training_callbacks.c +10612 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/utils/__init__.c +4907 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/utils/env_validator.c +14568 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/utils/onnx_helper.c +13528 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/utils/space_utils.c +19256 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/utils/validate_util.c +12828 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/v2/__init__.c +4958 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/v2/controller_component.c +16060 -0
- amesa_train_dev-0.20.5.dev13/dist/build_cython/amesa_train/v2/skill_processor_component.c +24296 -0
- amesa_train_dev-0.20.5.dev13/pyproject.toml +127 -0
- amesa_train_dev-0.20.5.dev13/setup.cfg +4 -0
- amesa_train_dev-0.20.5.dev13/setup.py +163 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: amesa-train-dev
|
|
3
|
+
Version: 0.20.5.dev13
|
|
4
|
+
Summary: a distributed trainer to be able to train agents across a cluster of machines
|
|
5
|
+
Author-email: Hunter Park <hunter@amesa.com>
|
|
6
|
+
Requires-Python: >=3.10, <3.13
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: amesa-api-dev>=0.20.5.dev13
|
|
9
|
+
Requires-Dist: amesa-core-dev>=0.20.5.dev13
|
|
10
|
+
Requires-Dist: networkx==3.1
|
|
11
|
+
Requires-Dist: docker==6.1.3
|
|
12
|
+
Requires-Dist: kubernetes==27.2.0
|
|
13
|
+
Requires-Dist: pytest-asyncio
|
|
14
|
+
Requires-Dist: redis
|
|
15
|
+
Requires-Dist: ray[rllib]==2.12.0
|
|
16
|
+
Requires-Dist: urllib3==1.26.12
|
|
17
|
+
Requires-Dist: torch==2.5.1
|
|
18
|
+
Requires-Dist: ruff
|
|
19
|
+
Requires-Dist: opencv-python-headless
|
|
20
|
+
Requires-Dist: imageio
|
|
21
|
+
Requires-Dist: onnx
|
|
22
|
+
Requires-Dist: onnxruntime
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: requires-python
|
|
26
|
+
|
|
27
|
+
# Amesa
|
|
28
|
+
|
|
29
|
+
Amesa helps you build Autonomous Agents! Through an easy SDK you get access to outscaled simulator training tools.
|
|
30
|
+
|
|
31
|
+
## Licenses / Seats
|
|
32
|
+
|
|
33
|
+
Amesa is an enterprise platform and requires an API key to use.
|
|
34
|
+
|
|
35
|
+
We offer 3 types of licenses:
|
|
36
|
+
|
|
37
|
+
- **Enterprise:** for enterprise projects and agent creations
|
|
38
|
+
- **Personal:** for personal usage and testing (typically offered to System Integrators)
|
|
39
|
+
- **Trial:** validate the Amesa platform (requires sales contact person)
|
|
40
|
+
|
|
41
|
+
One key is needed per user (seat-based licensing)
|
|
42
|
+
|
|
43
|
+
You can request an API Key through the following methods:
|
|
44
|
+
|
|
45
|
+
- [Discord](https://discord.gg/EQ3BgJt9NC)
|
|
46
|
+
- [Mail](mailto:sales@amesa.com?subject=REQUEST%20API%20KEY%20-%20COMPANY_NAME%20-%20NAME&body=Hi%2C%0D%0A%0D%0AI%20would%20like%20to%20request%20an%20API%20key%20for%20my%20company%20to%20get%20started%20with%20Amesa.%0D%0A%0D%0A*%20Company%20Name%3A%20COMPANY_NAME%0D%0A*%20Seats%3A%20NO_OF_SEATS%0D%0A*%20License%20Type%3A%20Enterprise%20%7C%20Personal%20%7C%20Trial%20%28keep%20what%20is%20required%29%0D%0A%0D%0AKind%20Regards%2C%0D%0ANAME%0D%0AFUNCTION)
|
|
47
|
+
|
|
48
|
+
## Getting Started
|
|
49
|
+
|
|
50
|
+
1. Download the Amesa SDK: `pip install amesa`
|
|
51
|
+
2. Request an API Key
|
|
52
|
+
3. Get a simulator or use one of the [prebuilt ones](https://hub.docker.com/u/composabl)
|
|
53
|
+
4. Create an Agent or see our [examples](https://github.com/Amesa/examples.amesa.com)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Amesa
|
|
2
|
+
|
|
3
|
+
Amesa helps you build Autonomous Agents! Through an easy SDK you get access to outscaled simulator training tools.
|
|
4
|
+
|
|
5
|
+
## Licenses / Seats
|
|
6
|
+
|
|
7
|
+
Amesa is an enterprise platform and requires an API key to use.
|
|
8
|
+
|
|
9
|
+
We offer 3 types of licenses:
|
|
10
|
+
|
|
11
|
+
- **Enterprise:** for enterprise projects and agent creations
|
|
12
|
+
- **Personal:** for personal usage and testing (typically offered to System Integrators)
|
|
13
|
+
- **Trial:** validate the Amesa platform (requires sales contact person)
|
|
14
|
+
|
|
15
|
+
One key is needed per user (seat-based licensing)
|
|
16
|
+
|
|
17
|
+
You can request an API Key through the following methods:
|
|
18
|
+
|
|
19
|
+
- [Discord](https://discord.gg/EQ3BgJt9NC)
|
|
20
|
+
- [Mail](mailto:sales@amesa.com?subject=REQUEST%20API%20KEY%20-%20COMPANY_NAME%20-%20NAME&body=Hi%2C%0D%0A%0D%0AI%20would%20like%20to%20request%20an%20API%20key%20for%20my%20company%20to%20get%20started%20with%20Amesa.%0D%0A%0D%0A*%20Company%20Name%3A%20COMPANY_NAME%0D%0A*%20Seats%3A%20NO_OF_SEATS%0D%0A*%20License%20Type%3A%20Enterprise%20%7C%20Personal%20%7C%20Trial%20%28keep%20what%20is%20required%29%0D%0A%0D%0AKind%20Regards%2C%0D%0ANAME%0D%0AFUNCTION)
|
|
21
|
+
|
|
22
|
+
## Getting Started
|
|
23
|
+
|
|
24
|
+
1. Download the Amesa SDK: `pip install amesa`
|
|
25
|
+
2. Request an API Key
|
|
26
|
+
3. Get a simulator or use one of the [prebuilt ones](https://hub.docker.com/u/composabl)
|
|
27
|
+
4. Create an Agent or see our [examples](https://github.com/Amesa/examples.amesa.com)
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Copyright (C) Amesa, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
|
|
5
|
+
from typing import Type, TypeVar, Union
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
import ray
|
|
9
|
+
|
|
10
|
+
import amesa_core.utils.logger as logger_util
|
|
11
|
+
|
|
12
|
+
T = TypeVar("T")
|
|
13
|
+
|
|
14
|
+
logger = logger_util.get_logger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ActorOptions(BaseModel):
|
|
18
|
+
name: str
|
|
19
|
+
|
|
20
|
+
# Do we detach the actor, maintaining it after references are removed
|
|
21
|
+
# https://docs.ray.io/en/latest/ray-core/actors/named-actors.html#actor-lifetimes
|
|
22
|
+
is_detached: bool = False
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class Actor:
|
|
26
|
+
"""
|
|
27
|
+
Define an Actor class that acts as a Proxy for Ray Actors
|
|
28
|
+
|
|
29
|
+
We use this to wrap the Ray Actor and provide a more intuitive API as well as resolve cython compatibility issues
|
|
30
|
+
more specifically it provides:
|
|
31
|
+
1. Not having to use `.remote`
|
|
32
|
+
2. Not having to use `ray.get` to get the result
|
|
33
|
+
3. Supporting async methods natively, which are converted to sync methods always.
|
|
34
|
+
This mainly resolves nested serialization issues causing pickle issues (ref. cannot pickle `_cython_3_2_2.coroutine`)
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
cls: Type[T],
|
|
40
|
+
name_or_options: Union[str, ActorOptions],
|
|
41
|
+
*actor_args,
|
|
42
|
+
**actor_kwargs
|
|
43
|
+
):
|
|
44
|
+
self._cls = cls
|
|
45
|
+
self._actor_args = actor_args
|
|
46
|
+
self._actor_kwargs = actor_kwargs
|
|
47
|
+
self._options = (
|
|
48
|
+
name_or_options
|
|
49
|
+
if isinstance(name_or_options, ActorOptions)
|
|
50
|
+
else ActorOptions(name=name_or_options)
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
self._handle = (
|
|
54
|
+
ray.remote(cls)
|
|
55
|
+
.options(
|
|
56
|
+
name=self._options.name,
|
|
57
|
+
lifetime="detached" if self._options.is_detached else None,
|
|
58
|
+
# By default, we create only if it doesn't exist
|
|
59
|
+
get_if_exists=True,
|
|
60
|
+
)
|
|
61
|
+
.remote(*actor_args, **actor_kwargs)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# # Catch all exceptions
|
|
65
|
+
# sys.excepthook = self._handle_excepthook
|
|
66
|
+
|
|
67
|
+
def __getattr__(self, attr_name) -> T:
|
|
68
|
+
"""
|
|
69
|
+
Execute this method on the Ray Actor Instance
|
|
70
|
+
|
|
71
|
+
Note: we make an exception for the reserved attributes _cls, _name and _handle
|
|
72
|
+
"""
|
|
73
|
+
if attr_name in ["_cls", "_name", "_handle"]:
|
|
74
|
+
return getattr(self, attr_name)
|
|
75
|
+
|
|
76
|
+
method = getattr(self._handle, attr_name)
|
|
77
|
+
return self._make_sync_proxy(method)
|
|
78
|
+
|
|
79
|
+
def _make_sync_proxy(self, method):
|
|
80
|
+
def proxy(*args, **kwargs):
|
|
81
|
+
result_id = method.remote(*args, **kwargs)
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
# Check if we need to use ray.get
|
|
85
|
+
if isinstance(result_id, ray.ObjectRef):
|
|
86
|
+
return ray.get(result_id)
|
|
87
|
+
else:
|
|
88
|
+
return result_id
|
|
89
|
+
except Exception as e:
|
|
90
|
+
logger.error(e)
|
|
91
|
+
# traceback.print_stack()
|
|
92
|
+
# Handle the exception here, e.g., by re-raising it or returning an error value
|
|
93
|
+
raise e
|
|
94
|
+
|
|
95
|
+
return proxy
|
|
96
|
+
|
|
97
|
+
def terminate(self):
|
|
98
|
+
"""
|
|
99
|
+
Terminate the actor
|
|
100
|
+
|
|
101
|
+
This uses a undocumented featured named `__ray_terminate__`
|
|
102
|
+
https://github.com/ray-project/ray/blob/0e77916b0415ce95550610f8b61764eeadf7aa6c/python/ray/actor.py#L1340
|
|
103
|
+
"""
|
|
104
|
+
self._handle.__ray_terminate__.remote()
|
|
105
|
+
ray.kill(self._handle)
|
|
106
|
+
|
|
107
|
+
def get_id(self):
|
|
108
|
+
"""
|
|
109
|
+
Get the Ray Actor ID
|
|
110
|
+
https://github.com/ray-project/ray/blob/master/python/ray/actor.py#L1038
|
|
111
|
+
"""
|
|
112
|
+
return self._handle._ray_actor_id
|
|
113
|
+
|
|
114
|
+
def get_language(self):
|
|
115
|
+
"""
|
|
116
|
+
Get the Ray Actor Language
|
|
117
|
+
https://github.com/ray-project/ray/blob/master/python/ray/actor.py#L1037C9-L1037C28
|
|
118
|
+
"""
|
|
119
|
+
return self._handle._ray_actor_language
|
|
120
|
+
|
|
121
|
+
def __getstate__(self):
|
|
122
|
+
state = {
|
|
123
|
+
"_cls": self._cls,
|
|
124
|
+
"_options": self._options,
|
|
125
|
+
"actor_args": self._actor_args,
|
|
126
|
+
"actor_kwargs": self._actor_kwargs,
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
# not every cls will have a __getstate__ method implemented
|
|
130
|
+
try:
|
|
131
|
+
additional_state = self._handle.__getstate__()
|
|
132
|
+
state["additional_state"] = additional_state
|
|
133
|
+
except:
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
return state
|
|
137
|
+
|
|
138
|
+
def __setstate__(self, state):
|
|
139
|
+
self._cls = state["_cls"]
|
|
140
|
+
self._options = state["_options"]
|
|
141
|
+
self._actor_args = state["actor_args"]
|
|
142
|
+
self._actor_kwargs = state["actor_kwargs"]
|
|
143
|
+
|
|
144
|
+
# Set the handle through Named Actors
|
|
145
|
+
# https://docs.ray.io/en/latest/ray-core/actors/named-actors.html#named-actors
|
|
146
|
+
|
|
147
|
+
try:
|
|
148
|
+
self._handle = ray.get_actor(self._options.name)
|
|
149
|
+
except:
|
|
150
|
+
# if we can't find the ray actor by name,
|
|
151
|
+
# then this is a new ray instance, and we must create it
|
|
152
|
+
self._handle = (
|
|
153
|
+
ray.remote(self._cls)
|
|
154
|
+
.options(
|
|
155
|
+
name=self._options.name,
|
|
156
|
+
lifetime="detached" if self._options.is_detached else None,
|
|
157
|
+
# By default, we create only if it doesn't exist
|
|
158
|
+
get_if_exists=True,
|
|
159
|
+
)
|
|
160
|
+
.remote(*self._actor_args, **self._actor_kwargs)
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
if "additional_state" in state:
|
|
164
|
+
self._handle.__setstate__(state["additional_state"])
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Copyright (C) Amesa, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
|
|
5
|
+
import time
|
|
6
|
+
from typing import Dict, Optional, Union
|
|
7
|
+
|
|
8
|
+
import amesa_core.utils.logger as logger_util
|
|
9
|
+
import ray
|
|
10
|
+
from amesa_core.metrics.metrics import Metrics
|
|
11
|
+
from amesa_core.metrics.metrics_config import MetricsConfig
|
|
12
|
+
|
|
13
|
+
import amesa_core.utils.logger as logger_util
|
|
14
|
+
logger = logger_util.get_logger(__name__)
|
|
15
|
+
|
|
16
|
+
IDX_ALL = -1
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class MetricsActor:
|
|
20
|
+
def __init__(self, config: Union[Dict, MetricsConfig, None] = None):
|
|
21
|
+
self.logger = logger_util.get_logger(__name__)
|
|
22
|
+
self.config = MetricsConfig.create(config)
|
|
23
|
+
self.metrics = Metrics(config)
|
|
24
|
+
self.log_previous_steps = 0
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def get_or_create(
|
|
28
|
+
config: Optional[MetricsConfig] = None,
|
|
29
|
+
) -> "ray.ObjectRef[MetricsActor]":
|
|
30
|
+
"""
|
|
31
|
+
Get the named actor or create it if it doesn't exist
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
The actor
|
|
35
|
+
"""
|
|
36
|
+
if config is None:
|
|
37
|
+
config = MetricsConfig()
|
|
38
|
+
|
|
39
|
+
actor_name = "MetricsActor"
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
ray.remote(MetricsActor)
|
|
43
|
+
.options(
|
|
44
|
+
name=actor_name,
|
|
45
|
+
# namespace="management",
|
|
46
|
+
# lifetime="detached",
|
|
47
|
+
get_if_exists=True,
|
|
48
|
+
)
|
|
49
|
+
.remote(config)
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def divide_log_frequency(self, value: int) -> int:
|
|
53
|
+
"""
|
|
54
|
+
Divide the log frequency by the value
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
value: The value
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
The divided value
|
|
61
|
+
"""
|
|
62
|
+
self.config.log_every_x_steps = int(self.config.log_every_x_steps / value)
|
|
63
|
+
|
|
64
|
+
def add_steps_collected(self, value: Union[float, int]):
|
|
65
|
+
"""
|
|
66
|
+
Set the samples collected
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
value: The value
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
None
|
|
73
|
+
"""
|
|
74
|
+
steps_collected = int(self.metrics.add_value("steps_collected", int(value)))
|
|
75
|
+
steps_to_collect = int(self.metrics.get_metric("steps_to_collect", 0))
|
|
76
|
+
|
|
77
|
+
# Reset when done
|
|
78
|
+
if steps_to_collect > 0 and steps_collected >= steps_to_collect:
|
|
79
|
+
self.metrics.set_value("steps_collected", 0)
|
|
80
|
+
self.log_previous_steps = 0
|
|
81
|
+
|
|
82
|
+
# Calculate the Δt and Σt for the timestamp
|
|
83
|
+
ts = time.time()
|
|
84
|
+
t_delta = round(self.metrics.diff_value("steps_collected_t", ts, 0), 3)
|
|
85
|
+
self.metrics.set_value("steps_collected_Δt", t_delta)
|
|
86
|
+
t_sigma = round(self.metrics.add_value("steps_collected_Σt", t_delta), 3)
|
|
87
|
+
|
|
88
|
+
# Print
|
|
89
|
+
if steps_collected - self.log_previous_steps >= self.config.log_every_x_steps:
|
|
90
|
+
self.print(steps_to_collect, steps_collected, t_delta, t_sigma)
|
|
91
|
+
self.log_previous_steps = steps_collected
|
|
92
|
+
|
|
93
|
+
def print(
|
|
94
|
+
self,
|
|
95
|
+
steps_to_collect: int,
|
|
96
|
+
steps_collected: int,
|
|
97
|
+
t_delta: float,
|
|
98
|
+
t_sigma: float,
|
|
99
|
+
):
|
|
100
|
+
"""
|
|
101
|
+
Print the metrics
|
|
102
|
+
"""
|
|
103
|
+
length_of_steps_to_collect = len(str(steps_to_collect))
|
|
104
|
+
steps_collected_str = str(steps_collected).rjust(length_of_steps_to_collect)
|
|
105
|
+
t_delta_str = (str(t_delta) + "s").rjust(8)
|
|
106
|
+
t_sigma_str = (str(t_sigma) + "s").rjust(8)
|
|
107
|
+
steps_per_second = round(
|
|
108
|
+
steps_collected / t_sigma if t_sigma > 0 else 0.0001, 3
|
|
109
|
+
)
|
|
110
|
+
steps_per_second_str = str(steps_per_second).rjust(8)
|
|
111
|
+
res = f"Gathering Experience: {steps_collected_str} / {steps_to_collect} | Δt: {t_delta_str} | Σt: {t_sigma_str} | steps/s: {steps_per_second_str}"
|
|
112
|
+
self.logger.info(res)
|
|
113
|
+
|
|
114
|
+
def set_steps_to_collect(self, value: int):
|
|
115
|
+
"""
|
|
116
|
+
Set the samples to collect
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
value: The value
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
None
|
|
123
|
+
"""
|
|
124
|
+
self.metrics.set_value("steps_to_collect", value)
|
|
125
|
+
|
|
126
|
+
def reset(self, metric: Optional[str] = None):
|
|
127
|
+
"""
|
|
128
|
+
Reset the metric given or everything if nothing
|
|
129
|
+
"""
|
|
130
|
+
self.log_previous_steps = 0
|
|
131
|
+
self.metrics.reset(metric)
|
|
132
|
+
|
|
133
|
+
# Also reset the other values that belong with the steps collected
|
|
134
|
+
if metric == "steps_collected":
|
|
135
|
+
self.metrics.set_value("steps_collected_t", time.time())
|
|
136
|
+
self.metrics.set_value("steps_collected_Δt", 0)
|
|
137
|
+
self.metrics.set_value("steps_collected_Σt", 0)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Copyright (C) Amesa, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
import ray
|
|
5
|
+
|
|
6
|
+
from amesa_core.config.trainer_config import TrainerConfig
|
|
7
|
+
from amesa_core.networking.network_mgr import NetworkMgr
|
|
8
|
+
import amesa_core.utils.logger as logger_util
|
|
9
|
+
|
|
10
|
+
logger = logger_util.get_logger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class NetworkMgrActor(NetworkMgr):
|
|
14
|
+
"""
|
|
15
|
+
Note: we do not use the `@ray.remote` decorator here because
|
|
16
|
+
ray does not support the decorator with Cython
|
|
17
|
+
see: https://github.com/ray-project/ray/issues/39736
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, config: TrainerConfig):
|
|
21
|
+
super().__init__(config)
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def create_actor(config: TrainerConfig) -> "ray.ObjectRef[NetworkMgrActor]":
|
|
25
|
+
"""
|
|
26
|
+
Create an actor
|
|
27
|
+
Note: we do not check if the actor exists already as we want the error. Causing the actor
|
|
28
|
+
to exist already causes unwanted behavior in tests
|
|
29
|
+
"""
|
|
30
|
+
actor_name = "NetworkMgrActor"
|
|
31
|
+
cls = ray.remote(NetworkMgrActor)
|
|
32
|
+
return cls.options(name=actor_name).remote(config)
|
|
33
|
+
|
|
34
|
+
def terminate(self):
|
|
35
|
+
"""
|
|
36
|
+
Terminate the actor
|
|
37
|
+
"""
|
|
38
|
+
logger.debug("Terminating sim watchdog on actor")
|
|
39
|
+
self.stop_watchdogs()
|
|
40
|
+
|
|
41
|
+
logger.debug("Terminating actor")
|
|
42
|
+
ray.actor.exit_actor()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Copyright (C) Amesa, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
|
|
5
|
+
from .env_config import EnvConfig
|
|
6
|
+
from .step_info import TeacherStepData, CoordinatedTeacherStepData
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"EnvConfig",
|
|
10
|
+
"TeacherStepData",
|
|
11
|
+
"CoordinatedTeacherStepData",
|
|
12
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Copyright (C) Amesa, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel
|
|
8
|
+
|
|
9
|
+
from amesa_core.networking.sim.client_config import ClientConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# Create a BaseModel implemention that is a Union of an any dict with ClientConfigBase
|
|
13
|
+
class EnvConfigBase(BaseModel):
|
|
14
|
+
amesa: ClientConfig = None
|
|
15
|
+
render: Optional[str] = None
|
|
16
|
+
|
|
17
|
+
class Config:
|
|
18
|
+
arbitrary_types_allowed = True
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class EnvConfig(EnvConfigBase):
|
|
22
|
+
def __init__(self, config={}):
|
|
23
|
+
super().__init__(**config)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copyright (C) Amesa, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
from typing import Dict, List, Optional, Union
|
|
5
|
+
from typing_extensions import Annotated
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, BeforeValidator, PlainSerializer
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def nd_array_custom_before_validator(x):
|
|
12
|
+
# custome before validation logic
|
|
13
|
+
return x
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def nd_array_custom_serializer(x):
|
|
17
|
+
# custome serialization logic
|
|
18
|
+
return str(x)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
NdArray = Annotated[
|
|
22
|
+
np.ndarray,
|
|
23
|
+
BeforeValidator(nd_array_custom_before_validator),
|
|
24
|
+
PlainSerializer(nd_array_custom_serializer, return_type=str),
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# Create a BaseModel implemention that is a Union of an any dict with ClientConfigBase
|
|
29
|
+
class TeacherStepData(BaseModel):
|
|
30
|
+
state: Dict[str, Union[float, dict, tuple, str]] = None
|
|
31
|
+
action: Union[NdArray, int, float, dict, tuple] = None
|
|
32
|
+
top_selector_action: Optional[Union[NdArray, int, float, dict, tuple]] = None
|
|
33
|
+
teacher_reward: float = None
|
|
34
|
+
coordinated_reward: Optional[Dict[str, float]] = None
|
|
35
|
+
teacher_success: bool = None
|
|
36
|
+
teacher_terminal: bool = None
|
|
37
|
+
|
|
38
|
+
class Config:
|
|
39
|
+
arbitrary_types_allowed = True
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class CoordinatedTeacherStepData(BaseModel):
|
|
43
|
+
state: Dict[str, Dict[str, Union[float, str]]] = None
|
|
44
|
+
action: Dict[str, Union[NdArray, int, float, dict, tuple]] = None
|
|
45
|
+
teacher_reward: Dict[str, float] = None
|
|
46
|
+
teacher_success: Dict[str, bool] = None
|
|
47
|
+
teacher_terminal: Dict[str, bool] = None
|
|
48
|
+
coordinated_reward: Optional[Dict[str, Dict[str, float]]] = None
|
|
49
|
+
coordinated_reward: Optional[List[float]] = None
|
|
50
|
+
|
|
51
|
+
class Config:
|
|
52
|
+
arbitrary_types_allowed = True
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Copyright (C) Amesa, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
|
|
5
|
+
from .env import AmesaEnv
|
|
6
|
+
from .env_multi_agent import AmesaEnvMultiAgent
|
|
7
|
+
from .env_mgr import EnvMgr
|