fix: typos and nonexistent calls
This commit is contained in:
parent
5a358fadde
commit
e40a4b979f
7 changed files with 52 additions and 50 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
# Sub-configs are loaded from the relative directories.
|
# Sub-configs are loaded from the relative directories.
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
|
- brittle_star_config
|
||||||
- experiment: base
|
- experiment: base
|
||||||
- logging: default
|
- logging: default
|
||||||
- ppo: default
|
- ppo: default
|
||||||
|
|
|
||||||
19
configs/ppo/smoke_test.yaml
Normal file
19
configs/ppo/smoke_test.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Fast PPO Configuration
|
||||||
|
# Lower timestep count for quick iterations/testing.
|
||||||
|
|
||||||
|
learning_rate: 0.0005
|
||||||
|
total_timesteps: 65536
|
||||||
|
num_envs: 512
|
||||||
|
num_steps: 128
|
||||||
|
anneal_lr: true
|
||||||
|
gamma: 0.99
|
||||||
|
gae_lambda: 0.95
|
||||||
|
num_minibatches: 4
|
||||||
|
update_epochs: 4
|
||||||
|
norm_adv: true
|
||||||
|
clip_coef: 0.2
|
||||||
|
clip_vloss: true
|
||||||
|
ent_coef: 0.01
|
||||||
|
vf_coef: 0.5
|
||||||
|
max_grad_norm: 0.5
|
||||||
|
target_kl: null
|
||||||
|
|
@ -23,7 +23,7 @@ def make_env(cfg: BrittleStarConfig) -> BrittleStarJaxEnvWrapper:
|
||||||
@hydra.main(config_path="../configs", config_name="main_config", version_base="1.3")
|
@hydra.main(config_path="../configs", config_name="main_config", version_base="1.3")
|
||||||
def main(dict_cfg: DictConfig):
|
def main(dict_cfg: DictConfig):
|
||||||
# 1. Convert DictConfig to structured dataclass
|
# 1. Convert DictConfig to structured dataclass
|
||||||
cfg: BrittleStarConfig = OmegaConf.to_object(dict_cfg)
|
config: BrittleStarConfig = OmegaConf.to_object(dict_cfg)
|
||||||
|
|
||||||
# 2. Setup run metadata
|
# 2. Setup run metadata
|
||||||
# Hydra changes CWD to the output directory by default.
|
# Hydra changes CWD to the output directory by default.
|
||||||
|
|
@ -31,25 +31,25 @@ def main(dict_cfg: DictConfig):
|
||||||
run_name = os.path.basename(run_dir)
|
run_name = os.path.basename(run_dir)
|
||||||
|
|
||||||
# 3. Initialize Logger
|
# 3. Initialize Logger
|
||||||
resolved_cfg_dict = OmegaConf.to_container(dict_cfg, resolve=True, throw_on_missing=True)
|
cfg_dict = OmegaConf.to_container(dict_cfg, resolve=True, throw_on_missing=True)
|
||||||
init_logger(
|
init_logger(
|
||||||
run_name=run_name,
|
run_name=run_name,
|
||||||
config=resolved_cfg_dict,
|
config=cfg_dict,
|
||||||
project_name=cfg.logging.wandb_project_name,
|
project_name=config.logging.wandb_project_name,
|
||||||
entity=cfg.logging.wandb_entity,
|
entity=config.logging.wandb_entity,
|
||||||
base_dir=os.path.dirname(run_dir),
|
base_dir=os.path.dirname(run_dir),
|
||||||
use_wandb=cfg.logging.track,
|
use_wandb=config.logging.track,
|
||||||
)
|
)
|
||||||
logger = get_logger()
|
logger = get_logger()
|
||||||
logger.info(f"Hydra-initialized run: {run_name}")
|
logger.info(f"Hydra-initialized run: {run_name}")
|
||||||
logger.info(f"Output directory: {run_dir}")
|
logger.info(f"Output directory: {run_dir}")
|
||||||
|
|
||||||
# 4. Setup Environment and Torch
|
# 4. Setup Environment and Torch
|
||||||
env = make_env(cfg)
|
env = make_env(config)
|
||||||
torch.backends.cudnn.deterministic = cfg.experiment.torch_deterministic
|
torch.backends.cudnn.deterministic = config.experiment.torch_deterministic
|
||||||
|
|
||||||
# 5. Train - pass structured config directly
|
# 5. Train - pass structured config directly
|
||||||
ppo_trainer = PPOTrainer(cfg, env, run_dir, run_name)
|
ppo_trainer = PPOTrainer(config, env, run_dir, run_name)
|
||||||
ppo_trainer.train()
|
ppo_trainer.train()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import List
|
from typing import List, Optional
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
@ -18,14 +18,20 @@ class ArchitectureConfig:
|
||||||
See docs/design/actor-critic.md for the full design rationale.
|
See docs/design/actor-critic.md for the full design rationale.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Input network: maps global observation to a hidden representation.
|
name: str = "base"
|
||||||
feature_extractor: LayerConfig = field(
|
|
||||||
default_factory=lambda: LayerConfig(hidden_dims=[64, 64], activation="tanh")
|
# Actor pipeline
|
||||||
)
|
sensor: Optional[LayerConfig] = None
|
||||||
# Output network: maps the hidden representation to a scalar value estimate.
|
propagator: Optional[LayerConfig] = None
|
||||||
critic: LayerConfig = field(
|
motor: Optional[LayerConfig] = None
|
||||||
default_factory=lambda: LayerConfig(hidden_dims=[], activation="tanh")
|
|
||||||
)
|
# Critic pipeline
|
||||||
|
feature_extractor: Optional[LayerConfig] = None
|
||||||
|
critic: Optional[LayerConfig] = None
|
||||||
|
|
||||||
|
# Decentralized
|
||||||
|
message_passing_steps: Optional[int] = None
|
||||||
|
topology_type: Optional[str] = None # Supported values: "ring", "fully_connected"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
@ -39,14 +45,7 @@ class CentralizedConfig(ArchitectureConfig):
|
||||||
See docs/design/actor-critic.md for the full design rationale.
|
See docs/design/actor-critic.md for the full design rationale.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Input network: maps the global observation to a hidden state.
|
name: str = "centralized"
|
||||||
sensor: LayerConfig = field(
|
|
||||||
default_factory=lambda: LayerConfig(hidden_dims=[64, 64], activation="tanh")
|
|
||||||
)
|
|
||||||
# Output network: projects hidden state to (mean, log_std) over all joints.
|
|
||||||
motor: LayerConfig = field(
|
|
||||||
default_factory=lambda: LayerConfig(hidden_dims=[], activation="tanh")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
@ -64,21 +63,4 @@ class DecentralizedConfig(ArchitectureConfig):
|
||||||
full design rationale.
|
full design rationale.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Input network: local observation -> initial hidden state per node.
|
name: str = "decentralized"
|
||||||
sensor: LayerConfig = field(
|
|
||||||
default_factory=lambda: LayerConfig(hidden_dims=[64, 64], activation="tanh")
|
|
||||||
)
|
|
||||||
# Message-passing network: aggregates neighbour messages and updates hidden state.
|
|
||||||
propagator: LayerConfig = field(
|
|
||||||
default_factory=lambda: LayerConfig(hidden_dims=[64, 64], activation="tanh")
|
|
||||||
)
|
|
||||||
# Output network: final hidden state -> joint offset for this node only.
|
|
||||||
motor: LayerConfig = field(
|
|
||||||
default_factory=lambda: LayerConfig(hidden_dims=[], activation="tanh")
|
|
||||||
)
|
|
||||||
|
|
||||||
# Number of synchronous message-passing rounds per control step.
|
|
||||||
message_passing_steps: int = 1
|
|
||||||
# Graph topology used for neighbour connections.
|
|
||||||
# Supported values: "ring", "fully_connected".
|
|
||||||
topology_type: str = "ring"
|
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ def register_configs() -> None:
|
||||||
cs.store(group="ppo", name="base_ppo", node=PPOConfig)
|
cs.store(group="ppo", name="base_ppo", node=PPOConfig)
|
||||||
|
|
||||||
# Architecture variants — swap via CLI: architecture=decentralized
|
# Architecture variants — swap via CLI: architecture=decentralized
|
||||||
cs.store(group="architecture", name="centralized", node=CentralizedConfig)
|
cs.store(group="architecture", name="centralized_schema", node=CentralizedConfig)
|
||||||
cs.store(group="architecture", name="decentralized", node=DecentralizedConfig)
|
cs.store(group="architecture", name="decentralized_schema", node=DecentralizedConfig)
|
||||||
|
|
||||||
# Environment configs
|
# Environment configs
|
||||||
cs.store(group="morphology", name="base_morphology", node=MorphologyConfig)
|
cs.store(group="morphology", name="base_morphology", node=MorphologyConfig)
|
||||||
|
|
|
||||||
|
|
@ -527,11 +527,11 @@ class PPOTrainer:
|
||||||
f"ETA {eta_str}"
|
f"ETA {eta_str}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if getattr(self.config.experiment, "debug_sanity", False):
|
if getattr(self.cfg.experiment, "debug_sanity", False):
|
||||||
self.logger.log(
|
self.logger.info(
|
||||||
"\n[SANITY CHECK] Successfully completed 1 epoch of data collection and gradient updates."
|
"\n[SANITY CHECK] Successfully completed 1 epoch of data collection and gradient updates."
|
||||||
)
|
)
|
||||||
self.logger.log("[SANITY CHECK] Gradients flowed without NaN. Exiting gracefully.")
|
self.logger.info("[SANITY CHECK] Gradients flowed without NaN. Exiting gracefully.")
|
||||||
break
|
break
|
||||||
|
|
||||||
if self.logging_cfg.save_model:
|
if self.logging_cfg.save_model:
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ def init_logger(**kwargs) -> "UnifiedLogger":
|
||||||
the output directories and set up all logging backends.
|
the output directories and set up all logging backends.
|
||||||
"""
|
"""
|
||||||
global _active_logger
|
global _active_logger
|
||||||
logger = UnifiedLogger(_set_as_global=False, **kwargs)
|
logger = UnifiedLogger(**kwargs)
|
||||||
_active_logger = logger
|
_active_logger = logger
|
||||||
return logger
|
return logger
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue