embodichain.learning.rl#
On-policy reinforcement learning pipeline.
Algorithms (PPO/GRPO), rollout buffers, collectors, and the training entry point; rollout data flows as TensorDict objects.
Overview#
The embodichain.learning.rl package contains algorithm registries, rollout
collection logic, policy/model builders, and training entry points.
Submodules
Algorithm registry and construction helpers (
BaseAlgorithm,PPO,GRPO,compute_gae,build_algo).On-policy rollout buffer (
RolloutBuffer) owning preallocatedTensorDictstorage, plus minibatch iteration helpers.Collectors that step vectorized environments and assemble rollout data into a preallocated
TensorDictlayout.RL policies and registration, loaded on demand.
Policy evaluation configuration for
embodichain eval-policy.RL helper utilities: algorithm config, optimizers, and observation helpers.
Top-level APIs
DifferentiableTrainerCoordinate APG updates, full rollouts, and optional TBPTT boundaries.
DifferentiableTrainerCfgConfiguration for segmented or complete graph-preserving training.
DifferentiableRolloutSpecDescribe one independent complete rollout used for a gradient microbatch.
DifferentiableVecEnvBatched env that preserves the autograd path through
step.
LearningVecEnvStructural interface shared by lightweight vector environments.
ScheduledDifferentiableVecEnvDifferentiable env that schedules variable independent rollouts.
RunningObservationNormalizerNormalize continuous observation fields with running Welford statistics.
BatchedGradientNormStatsAccumulate row-wise adjoint norm and clipping statistics on-device.
build_learning_env(name, *, num_envs, ...)Build a registered lightweight vector environment.
clip_batched_gradient_norm(gradient, max_norm)Clip each batch row without shortening the differentiable time horizon.
evaluate_episodes(*, policy, env, ...[, ...])Evaluate exactly
num_episodescompleted asynchronous episodes.
get_trainer_class(algorithm)Return the trainer compatible with
algorithm.
register_learning_env(name[, factory, override])Register a lightweight vector-environment factory.
stratified_rollout_value(index, minimum, maximum)Cycle uniformly through an integer range and rotate each cycle's order.
Algorithms#
Algorithm registry and construction helpers (BaseAlgorithm, PPO, GRPO, compute_gae, build_algo).
Classes:
Optimize policy parameters through differentiable rollout rewards. |
|
Analytic policy-gradient config. |
|
Base class for RL algorithms. |
|
Group Relative Policy Optimization on top of TensorDict rollouts. |
|
Configuration for GRPO. |
|
PPO algorithm consuming TensorDict rollouts. |
|
Configuration for the PPO algorithm. |
|
Rollout semantics required by an algorithm. |
Functions:
|
|
|
Compute per-environment returns up to the first terminal transition. |
|
Compute GAE over a rollout stored as [num_envs, time + 1]. |
|
Compute one discounted return per environment within a rollout segment. |
- class embodichain.learning.rl.algo.APG[source]#
Bases:
BaseAlgorithm[DifferentiableRollout]Optimize policy parameters through differentiable rollout rewards.
Methods:
__init__(cfg, policy)accumulate_complete_rollout(rollout, *[, ...])Accumulate one independent full-horizon rollout.
accumulate_segment(rollout)Accumulate gradients from one TBPTT segment without stepping the optimizer.
Clip gradients and apply one optimizer step.
update(rollout)Apply one pathwise-gradient update from a rollout segment.
Attributes:
- accumulate_complete_rollout(rollout, *, objective_scale=1.0, accumulation_scale=1.0)[source]#
Accumulate one independent full-horizon rollout.
- Parameters:
rollout (
DifferentiableRollout) – Complete graph-preserving trajectory.objective_scale (
float|Tensor) – Scalar or per-environment return multiplier.accumulation_scale (
float) – Loss multiplier, normally reciprocal to the number of independent rollout microbatches in one update.
- Raises:
RuntimeError – If no APG update is active.
ValueError – If the rollout, scaling, or accumulation factor is invalid.
- Return type:
None
- accumulate_segment(rollout)[source]#
Accumulate gradients from one TBPTT segment without stepping the optimizer.
- Return type:
None
-
device:
device#
-
lr_scheduler:
LRScheduler|None#
-
optimizer:
Optimizer#
- rollout_kind = 'differentiable'#
- class embodichain.learning.rl.algo.APGCfg[source]#
Bases:
AlgorithmCfgAnalytic policy-gradient config.
gammaapplies within each TBPTT segment and restarts after done.Methods:
__init__([device, optimizer, lr_scheduler, ...])copy(**kwargs)Return a new object replacing specified fields with new values.
replace(**kwargs)Return a new object replacing specified fields with new values.
to_dict()Convert an object into dictionary recursively.
validate([prefix])Check the validity of configclass object.
Attributes:
- __init__(device=<factory>, optimizer=<factory>, lr_scheduler=<factory>, batch_size=<factory>, gamma=<factory>, gae_lambda=<factory>, max_grad_norm=<factory>, ent_coef=<factory>, skip_nonfinite_updates=<factory>, max_grad_norm_before_clip=<factory>)#
- batch_size: int#
- copy(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- device: str#
- ent_coef: float#
- gae_lambda: float#
- gamma: float#
- lr_scheduler: LRSchedulerCfg#
- max_grad_norm: float#
- max_grad_norm_before_clip: float#
- optimizer: OptimizerCfg#
- replace(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- skip_nonfinite_updates: bool#
- to_dict()#
Convert an object into dictionary recursively.
Note
Ignores all names starting with “__” (i.e. built-in methods).
- Parameters:
obj (
object) – An instance of a class to convert.- Raises:
ValueError – When input argument is not an object.
- Return type:
dict[str,Any]- Returns:
Converted dictionary mapping.
- validate(prefix='')#
Check the validity of configclass object.
This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.
- Parameters:
obj (
object) – The object to check.prefix (
str) – The prefix to add to the missing fields. Defaults to ‘’.
- Return type:
list[str]- Returns:
A list of missing fields.
- Raises:
TypeError – When the object is not a valid configuration object.
- class embodichain.learning.rl.algo.BaseAlgorithm[source]#
Bases:
ABC,Generic[RolloutT]Base class for RL algorithms.
Methods:
bind_schedule(*, total_updates)Bind horizon-dependent LR schedules from the training budget.
load_state_dict(state, *[, resume_scheduler])Restore optimization state or restart its configured LR curve.
Return optimizer and learning-rate state for a trainer checkpoint.
update(rollout)Update policy using collected data and return training losses.
validate_state_dict(state, *[, resume_scheduler])Check optimization structure before changing the live algorithm.
Attributes:
- bind_schedule(*, total_updates)[source]#
Bind horizon-dependent LR schedules from the training budget.
- Return type:
None
-
device:
device#
- load_state_dict(state, *, resume_scheduler='restore')[source]#
Restore optimization state or restart its configured LR curve.
- Parameters:
state (
dict[str,Any]) – Optimization fields returned bystate_dict().resume_scheduler (
str) – Restore the saved LR curve, or restart the configured curve while retaining optimizer momentum.
- Return type:
None
-
lr_scheduler:
LRScheduler|None#
-
optimizer:
Optimizer#
- rollout_kind = 'standard'#
- state_dict()[source]#
Return optimizer and learning-rate state for a trainer checkpoint.
- Return type:
dict[str,Any]- Returns:
Optimizer state, scheduler configuration/progress, and any pending restart that binds the schedule to the remaining update budget.
- abstract update(rollout)[source]#
Update policy using collected data and return training losses.
- Return type:
Dict[str,float]
- validate_state_dict(state, *, resume_scheduler='restore')[source]#
Check optimization structure before changing the live algorithm.
- Parameters:
state (
dict[str,Any]) – Optimization fields returned bystate_dict().resume_scheduler (
str) – Restore the saved curve or restart configuration.
- Raises:
ValueError – If the mode, optimizer layout, or scheduler fields differ.
- Return type:
None
- class embodichain.learning.rl.algo.GRPO[source]#
Bases:
BaseAlgorithm[TensorDict]Group Relative Policy Optimization on top of TensorDict rollouts.
Methods:
__init__(cfg, policy)Include the fixed KL reference policy in optimization state.
update(rollout)Update policy using collected data and return training losses.
validate_state_dict(state, *[, resume_scheduler])Reject checkpoints missing the active KL reference policy.
- state_dict()[source]#
Include the fixed KL reference policy in optimization state.
- Return type:
dict[str,Any]- Returns:
Optimization state with the KL reference when enabled.
- update(rollout)[source]#
Update policy using collected data and return training losses.
- Return type:
Dict[str,float]
- validate_state_dict(state, *, resume_scheduler='restore')[source]#
Reject checkpoints missing the active KL reference policy.
- Parameters:
state (
dict[str,Any]) – Optimization and reference-policy checkpoint fields.resume_scheduler (
str) – Restore the saved curve or restart configuration.
- Raises:
ValueError – If the optimizer or active reference policy is incompatible.
- Return type:
None
- class embodichain.learning.rl.algo.GRPOCfg[source]#
Bases:
AlgorithmCfgConfiguration for GRPO.
Methods:
__init__([device, optimizer, lr_scheduler, ...])copy(**kwargs)Return a new object replacing specified fields with new values.
replace(**kwargs)Return a new object replacing specified fields with new values.
to_dict()Convert an object into dictionary recursively.
validate([prefix])Check the validity of configclass object.
Attributes:
- __init__(device=<factory>, optimizer=<factory>, lr_scheduler=<factory>, batch_size=<factory>, gamma=<factory>, gae_lambda=<factory>, max_grad_norm=<factory>, n_epochs=<factory>, clip_coef=<factory>, ent_coef=<factory>, kl_coef=<factory>, group_size=<factory>, eps=<factory>, reset_every_rollout=<factory>, truncate_at_first_done=<factory>)#
- batch_size: int#
- clip_coef: float#
- copy(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- device: str#
- ent_coef: float#
- eps: float#
- gae_lambda: float#
- gamma: float#
- group_size: int#
- kl_coef: float#
- lr_scheduler: LRSchedulerCfg#
- max_grad_norm: float#
- n_epochs: int#
- optimizer: OptimizerCfg#
- replace(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- reset_every_rollout: bool#
- to_dict()#
Convert an object into dictionary recursively.
Note
Ignores all names starting with “__” (i.e. built-in methods).
- Parameters:
obj (
object) – An instance of a class to convert.- Raises:
ValueError – When input argument is not an object.
- Return type:
dict[str,Any]- Returns:
Converted dictionary mapping.
- truncate_at_first_done: bool#
- validate(prefix='')#
Check the validity of configclass object.
This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.
- Parameters:
obj (
object) – The object to check.prefix (
str) – The prefix to add to the missing fields. Defaults to ‘’.
- Return type:
list[str]- Returns:
A list of missing fields.
- Raises:
TypeError – When the object is not a valid configuration object.
- class embodichain.learning.rl.algo.PPO[source]#
Bases:
BaseAlgorithm[TensorDict]PPO algorithm consuming TensorDict rollouts.
Methods:
- class embodichain.learning.rl.algo.PPOCfg[source]#
Bases:
AlgorithmCfgConfiguration for the PPO algorithm.
Methods:
__init__([device, optimizer, lr_scheduler, ...])copy(**kwargs)Return a new object replacing specified fields with new values.
replace(**kwargs)Return a new object replacing specified fields with new values.
to_dict()Convert an object into dictionary recursively.
validate([prefix])Check the validity of configclass object.
Attributes:
- __init__(device=<factory>, optimizer=<factory>, lr_scheduler=<factory>, batch_size=<factory>, gamma=<factory>, gae_lambda=<factory>, max_grad_norm=<factory>, n_epochs=<factory>, clip_coef=<factory>, ent_coef=<factory>, vf_coef=<factory>, action_bound_coef=<factory>, use_clipped_value_loss=<factory>, schedule=<factory>, desired_kl=<factory>, minimum_learning_rate=<factory>, maximum_learning_rate=<factory>, num_mini_batches=<factory>, normalize_advantage_per_mini_batch=<factory>)#
- action_bound_coef: float#
- batch_size: int#
- clip_coef: float#
- copy(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- desired_kl: float | None#
- device: str#
- ent_coef: float#
- gae_lambda: float#
- gamma: float#
- lr_scheduler: LRSchedulerCfg#
- max_grad_norm: float#
- maximum_learning_rate: float#
- minimum_learning_rate: float#
- n_epochs: int#
- normalize_advantage_per_mini_batch: bool#
- num_mini_batches: int | None#
- optimizer: OptimizerCfg#
- replace(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- schedule: str#
- to_dict()#
Convert an object into dictionary recursively.
Note
Ignores all names starting with “__” (i.e. built-in methods).
- Parameters:
obj (
object) – An instance of a class to convert.- Raises:
ValueError – When input argument is not an object.
- Return type:
dict[str,Any]- Returns:
Converted dictionary mapping.
- use_clipped_value_loss: bool#
- validate(prefix='')#
Check the validity of configclass object.
This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.
- Parameters:
obj (
object) – The object to check.prefix (
str) – The prefix to add to the missing fields. Defaults to ‘’.
- Return type:
list[str]- Returns:
A list of missing fields.
- Raises:
TypeError – When the object is not a valid configuration object.
- vf_coef: float#
- class embodichain.learning.rl.algo.RolloutKind[source]#
Bases:
str,EnumRollout semantics required by an algorithm.
Attributes:
Methods:
__new__(value)- DIFFERENTIABLE = 'differentiable'#
- STANDARD = 'standard'#
- __new__(value)#
- embodichain.learning.rl.algo.build_algo(name, cfg_kwargs, policy, device, *, distributed=False)[source]#
- embodichain.learning.rl.algo.complete_discounted_return(rollout, gamma)[source]#
Compute per-environment returns up to the first terminal transition.
Unlike segmented TBPTT returns, complete-rollout discounting never restarts after
done. This excludes rewards emitted by any automatic reset during the fixed full horizon.- Parameters:
rollout (
DifferentiableRollout) – Complete graph-preserving trajectory.gamma (
float) – Per-step discount factor.
- Return type:
Tensor- Returns:
One masked discounted return per environment.
- Raises:
ValueError – If the rollout is empty.
- embodichain.learning.rl.algo.compute_gae(rollout, gamma, gae_lambda)[source]#
Compute GAE over a rollout stored as [num_envs, time + 1].
- Parameters:
rollout (
TensorDict) – Rollout TensorDict where value[:, -1] stores the bootstrap value for the final observation and transition-only fields reserve their last slot as padding.gamma (
float) – Discount factor.gae_lambda (
float) – GAE lambda coefficient.
- Return type:
tuple[Tensor,Tensor]- Returns:
Tuple of (advantages, returns), both shaped [num_envs, time].
Environments#
Contracts and registration helpers for lightweight learning environments.
Classes:
Describe one independent complete rollout used for a gradient microbatch. |
|
Batched env that preserves the autograd path through |
|
Structural interface shared by lightweight vector environments. |
|
Differentiable env that schedules variable independent rollouts. |
Functions:
|
Build a registered lightweight vector environment. |
Return registered lightweight environment names. |
|
|
Register a lightweight vector-environment factory. |
|
Cycle uniformly through an integer range and rotate each cycle's order. |
- class embodichain.learning.rl.env.DifferentiableRolloutSpec[source]#
Bases:
objectDescribe one independent complete rollout used for a gradient microbatch.
- Parameters:
num_steps (
int) – Full rollout horizon. The trainer must not detach or truncate it.objective_scale (
float|Tensor) – Per-environment or scalar multiplier applied to returns.metadata (
Mapping[str,float]) – Scalar labels recorded with training metrics.
Methods:
__init__(num_steps[, objective_scale, metadata])Attributes:
- __init__(num_steps, objective_scale=1.0, metadata=<factory>)#
-
metadata:
Mapping[str,float]#
-
num_steps:
int#
-
objective_scale:
float|Tensor= 1.0#
- class embodichain.learning.rl.env.DifferentiableVecEnv[source]#
Bases:
LearningVecEnv,ProtocolBatched env that preserves the autograd path through
step.detach_stateis the truncated-backpropagation boundary: detach differentiable internal state and return the current observation without resetting or resampling the episode. Finished rows must auto-reset insidestep, returning the terminal reward/done with the next initial observation.Methods:
Detach internal state and return its current detached observation.
- class embodichain.learning.rl.env.LearningVecEnv[source]#
Bases:
ProtocolStructural interface shared by lightweight vector environments.
Methods:
__init__(*args, **kwargs)close()Release owned resources.
reset(*[, seed, options])Reset all environments and return the initial observation.
step(action)Advance all environments by one step.
Attributes:
- __init__(*args, **kwargs)#
-
device:
device#
-
num_envs:
int#
- reset(*, seed=None, options=None)[source]#
Reset all environments and return the initial observation.
- Return type:
tuple[Tensor|TensorDict,dict[str,Any]]
-
single_action_space:
Space#
-
single_observation_space:
Space#
- class embodichain.learning.rl.env.ScheduledDifferentiableVecEnv[source]#
Bases:
DifferentiableVecEnv,ProtocolDifferentiable env that schedules variable independent rollouts.
The trainer calls
prepare_differentiable_rollout()immediately before resetting the environment. Implementations may select task difficulty for the next reset, such as an ordered-waypoint count, and must return the full horizon and objective scaling for that selection.Methods:
prepare_differentiable_rollout(rollout_index)Configure the next reset and return its complete-rollout contract.
- embodichain.learning.rl.env.build_learning_env(name, *, num_envs, device, **cfg)[source]#
Build a registered lightweight vector environment.
- Return type:
- embodichain.learning.rl.env.get_registered_learning_env_names()[source]#
Return registered lightweight environment names.
- Return type:
list[str]
- embodichain.learning.rl.env.register_learning_env(name, factory=None, *, override=False)[source]#
Register a lightweight vector-environment factory.
The function supports both
@register_learning_env("Name")and directregister_learning_env("Name", Factory)use.- Return type:
Callable[[Callable[...,LearningVecEnv]],Callable[...,LearningVecEnv]] |Callable[...,LearningVecEnv]
- embodichain.learning.rl.env.stratified_rollout_value(index, minimum, maximum)[source]#
Cycle uniformly through an integer range and rotate each cycle’s order.
- Parameters:
index (
int) – Zero-based rollout index.minimum (
int) – Inclusive minimum scheduled value.maximum (
int) – Inclusive maximum scheduled value.
- Return type:
int- Returns:
Scheduled integer for
index.- Raises:
ValueError – If the inclusive range is empty.
Evaluation#
Shared deterministic episode evaluation for all RL trainers.
Functions:
|
Move a flat policy action to the task environment's device. |
|
Evaluate exactly |
|
Run the same deterministic Policy call used by RL evaluation. |
|
Flatten one Environment observation in the configured input order. |
- embodichain.learning.rl.evaluation.convert_policy_action_for_env(env, action)[source]#
Move a flat policy action to the task environment’s device.
- Parameters:
env (
Any) – Environment that owns action preprocessing and simulation state.action (
Tensor) – Flat action produced on the Policy inference device.
- Return type:
Any- Returns:
Action on the Environment device. The environment owns action-term processing so that policy actions are validated and applied exactly once inside
EmbodiedEnv.step().
- embodichain.learning.rl.evaluation.evaluate_episodes(*, policy, env, num_episodes, device, seed=None, on_step=None, observation_transform=None)[source]#
Evaluate exactly
num_episodescompleted asynchronous episodes.- Parameters:
policy (
Module) – Policy evaluated with deterministic actions.env (
Any) – Vector environment with automatic row reset.num_episodes (
int) – Exact number of completed episodes to collect.device (
device|str) – Policy device.seed (
int|None) – Optional environment reset seed.on_step (
Callable[[dict[str,Any]],None] |None) – Optional callback for raw step info.observation_transform (
Callable[[Tensor],Tensor] |None) – Optional frozen preprocessing transform, such as a running observation normalizer.
- Return type:
dict[str,float]
Gradient Stabilization#
Gradient stabilization primitives for differentiable rollouts.
Classes:
Accumulate row-wise adjoint norm and clipping statistics on-device. |
Functions:
|
Clip each batch row without shortening the differentiable time horizon. |
- class embodichain.learning.rl.gradients.BatchedGradientNormStats[source]#
Bases:
objectAccumulate row-wise adjoint norm and clipping statistics on-device.
- Parameters:
device (
device|str) – Device on which hook-side counters are accumulated.
Methods:
- embodichain.learning.rl.gradients.clip_batched_gradient_norm(gradient, max_norm, stats=None)[source]#
Clip each batch row without shortening the differentiable time horizon.
Norms are computed with max-absolute-value scaling to avoid overflow in float32. A non-finite row is replaced with zeros while finite rows remain independent from one another.
- Parameters:
gradient (
Tensor) – Tensor whose first dimension identifies independent rows.max_norm (
float) – Maximum L2 norm per row. Zero disables clipping.stats (
BatchedGradientNormStats|None) – Optional on-device accumulator populated before clipping.
- Return type:
Tensor- Returns:
A finite tensor with the same shape, dtype, and device as
gradient.- Raises:
ValueError – If
max_normis negative orgradientis not batched.
Observation Normalization#
Running statistics for learning-environment observations.
Classes:
Normalize continuous observation fields with running Welford statistics. |
- class embodichain.learning.rl.normalization.RunningObservationNormalizer[source]#
Bases:
objectNormalize continuous observation fields with running Welford statistics.
The optional mask leaves semantic fields such as one-hot encodings and validity bits unchanged while still tracking a single flat observation. Statistics are updated only when
update()is called;normalize()is side-effect free so a complete differentiable rollout uses one frozen normalization transform.- Parameters:
observation_dim (
int) – Flat observation dimension.device (
device|str) – Device used for the running statistics.normalize_mask (
Tensor|None) – Boolean mask whereTrueselects normalized fields.initial_count (
float) – Positive pseudo-count used to stabilize the first update.
Methods:
__init__(observation_dim, device[, ...])load_state_dict(state_dict)Restore statistics while validating their observation layout.
normalize(observations)Apply the frozen running transform without detaching observations.
Return a device-independent checkpoint payload.
update(observations)Merge one observation batch into the running statistics.
- load_state_dict(state_dict)[source]#
Restore statistics while validating their observation layout.
- Parameters:
state_dict (
Mapping[str,Any]) – Payload produced bystate_dict().- Raises:
ValueError – If dimensions or the pseudo-count are invalid.
- Return type:
None
- normalize(observations)[source]#
Apply the frozen running transform without detaching observations.
- Parameters:
observations (
Tensor) – Tensor ending in the configured observation dimension.- Return type:
Tensor- Returns:
Tensor with continuous fields normalized and semantic fields intact.
- Raises:
ValueError – If the trailing observation dimension is incompatible.
Routing#
Trainer routing based on an algorithm’s rollout semantics.
Functions:
|
Return the trainer compatible with |
- embodichain.learning.rl.routing.get_trainer_class(algorithm)[source]#
Return the trainer compatible with
algorithm.- Return type:
type[Trainer] |type[DifferentiableTrainer]
Differentiable Trainer#
Training orchestration for truncated differentiable rollouts.
Classes:
Coordinate APG updates, full rollouts, and optional TBPTT boundaries. |
|
Configuration for segmented or complete graph-preserving training. |
- class embodichain.learning.rl.differentiable_trainer.DifferentiableTrainer[source]#
Bases:
objectCoordinate APG updates, full rollouts, and optional TBPTT boundaries.
Methods:
__init__(cfg, env, policy, algorithm[, ...])Return the current in-memory training summary.
load_checkpoint(path, *[, resume_scheduler])Validate and restore learning state, starting with a fresh rollout.
save_checkpoint([path])Atomically save learning state and update the run index.
train([total_timesteps, total_updates])Train to a vector-transition or optimizer-update budget.
- __init__(cfg, env, policy, algorithm, writer=None, eval_env=None, observation_normalizer=None)[source]#
- load_checkpoint(path, *, resume_scheduler='restore')[source]#
Validate and restore learning state, starting with a fresh rollout.
- Parameters:
path (
str|Path) – Checkpoint file, including existing APG schema-v1 files.resume_scheduler (
str) – Restore the saved LR curve or restart the configured curve while preserving optimizer momentum.
- Return type:
None
- save_checkpoint(path=None)[source]#
Atomically save learning state and update the run index.
- Parameters:
path (
str|Path|None) – Destination, or the current step’s default checkpoint path.- Return type:
str- Returns:
Saved checkpoint path.
- train(total_timesteps=None, *, total_updates=None)[source]#
Train to a vector-transition or optimizer-update budget.
total_updatesis the stable budget for scheduled variable-horizon training. Exactly one budget may be supplied.- Parameters:
total_timesteps (
int|None) – Optional absolute vector-transition budget.total_updates (
int|None) – Optional absolute optimizer-update budget.
- Return type:
dict[str,Any]- Returns:
Current training counters, metrics, histories, and checkpoint paths.
- Raises:
ValueError – If neither/both budgets are supplied or one is negative.
- class embodichain.learning.rl.differentiable_trainer.DifferentiableTrainerCfg[source]#
Bases:
objectConfiguration for segmented or complete graph-preserving training.
Methods:
__init__([segment_length, update_horizon, ...])copy(**kwargs)Return a new object replacing specified fields with new values.
replace(**kwargs)Return a new object replacing specified fields with new values.
to_dict()Convert an object into dictionary recursively.
validate([prefix])Check the validity of configclass object.
Attributes:
- __init__(segment_length=<factory>, update_horizon=<factory>, rollout_mode=<factory>, gradient_accumulation_steps=<factory>, deterministic_actions=<factory>, clip_actions_to_space=<factory>, action_adjoint_max_norm=<factory>, normalize_observations=<factory>, rollout_seed=<factory>, checkpoint_dir=<factory>, experiment_name=<factory>, save_frequency_updates=<factory>, eval_frequency_steps=<factory>, num_eval_episodes=<factory>, eval_seed=<factory>, use_wandb=<factory>, best_eval_metric=<factory>, best_eval_mode=<factory>)#
-
action_adjoint_max_norm:
float#
-
best_eval_metric:
str#
-
best_eval_mode:
str#
-
checkpoint_dir:
str#
-
clip_actions_to_space:
bool#
- copy(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
-
deterministic_actions:
bool#
-
eval_frequency_steps:
int#
-
eval_seed:
int|None#
-
experiment_name:
str#
-
gradient_accumulation_steps:
int#
-
normalize_observations:
bool#
-
num_eval_episodes:
int#
- replace(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
-
rollout_mode:
str#
-
rollout_seed:
int|None#
-
save_frequency_updates:
int#
-
segment_length:
int#
- to_dict()#
Convert an object into dictionary recursively.
Note
Ignores all names starting with “__” (i.e. built-in methods).
- Parameters:
obj (
object) – An instance of a class to convert.- Raises:
ValueError – When input argument is not an object.
- Return type:
dict[str,Any]- Returns:
Converted dictionary mapping.
-
update_horizon:
int|None#
-
use_wandb:
bool#
- validate(prefix='')#
Check the validity of configclass object.
This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.
- Parameters:
obj (
object) – The object to check.prefix (
str) – The prefix to add to the missing fields. Defaults to ‘’.
- Return type:
list[str]- Returns:
A list of missing fields.
- Raises:
TypeError – When the object is not a valid configuration object.
Rollout Buffer#
On-policy rollout buffer (RolloutBuffer) owning preallocated TensorDict storage, plus minibatch iteration helpers.
Classes:
Single-rollout buffer backed by a preallocated TensorDict. |
Functions:
|
Yield shuffled minibatches from a flattened rollout. |
|
Build a transition-aligned TensorDict from a rollout. |
- class embodichain.learning.rl.buffer.RolloutBuffer[source]#
Bases:
objectSingle-rollout buffer backed by a preallocated TensorDict.
The shared rollout uses a uniform [num_envs, time + 1] layout. For transition-only fields such as action, reward, and done, the final time index is reused as padding so the collector, environment, and algorithms can share a single TensorDict batch shape.
Methods:
__init__(num_envs, rollout_len, obs_dim, ...)add(rollout)Mark the shared rollout as ready for consumption.
get([flatten])Return the stored rollout and clear the buffer.
is_full()Return whether a rollout is waiting to be consumed.
Return the shared rollout TensorDict for collector write-in.
Attributes:
- __init__(num_envs, rollout_len, obs_dim, action_dim, device, critic_obs_dim=None, distribution_param_dim=None)[source]#
- property buffer: TensorDict#
- embodichain.learning.rl.buffer.iterate_minibatches(rollout, batch_size, device)[source]#
Yield shuffled minibatches from a flattened rollout.
- Return type:
Iterator[TensorDict]
- embodichain.learning.rl.buffer.transition_view(rollout, flatten=False)[source]#
Build a transition-aligned TensorDict from a rollout.
The shared rollout uses a uniform [num_envs, time + 1] layout. For transition-only fields such as action, reward, and done, the final slot is reserved as padding so that all rollout fields share the same batch shape. This helper drops that padded slot and exposes the valid transition slices as a TensorDict with batch shape [num_envs, time].
- Parameters:
rollout (
TensorDict) – Rollout TensorDict with root batch shape [num_envs, time + 1].flatten (
bool) – If True, return a flattened [num_envs * time] view.
- Return type:
TensorDict- Returns:
TensorDict containing transition-aligned fields.
Collectors#
Collectors that step vectorized environments and assemble rollout data into a preallocated TensorDict layout.
Classes:
Base class for rollout collectors. |
|
Collect graph-preserving rollouts without a preallocated buffer. |
|
An immutable sequence of graph-preserving transitions. |
|
One graph-preserving environment transition. |
|
Synchronously collect rollouts from a vectorized environment. |
- class embodichain.learning.rl.collector.BaseCollector[source]#
Bases:
ABCBase class for rollout collectors.
Methods:
collect(num_steps[, rollout, on_step_callback])Collect a rollout and return it as a TensorDict.
- class embodichain.learning.rl.collector.DifferentiableCollector[source]#
Bases:
objectCollect graph-preserving rollouts without a preallocated buffer.
Methods:
__init__(env, policy, device, *[, ...])collect(num_steps, *[, deterministic, ...])Collect a graph-preserving rollout segment.
Start a new truncated-backpropagation segment.
reset(*[, seed])Reset the environment and collector state.
- __init__(env, policy, device, *, observation_normalizer=None, clip_actions_to_space=False, action_adjoint_max_norm=0.0)[source]#
- collect(num_steps, *, deterministic=False, on_step_callback=None)[source]#
Collect a graph-preserving rollout segment.
- Parameters:
num_steps (
int) – Number of differentiable environment steps.deterministic (
bool) – Whether to use deterministic policy actions.on_step_callback (
Optional[Callable[[DifferentiableTransition],None]]) – Optional callback invoked with each transition.
- Return type:
- Returns:
An immutable differentiable rollout.
- Raises:
ValueError – If
num_stepsis not positive.
- class embodichain.learning.rl.collector.DifferentiableRollout[source]#
Bases:
objectAn immutable sequence of graph-preserving transitions.
Methods:
__init__(initial_observation, transitions[, ...])Attributes:
Return rows active before each step, stopping after the first done.
Return the observation after the final transition.
Return the number of collected transitions.
Stack the raw policy observations.
Stack rewards as
[time, num_envs]without detaching them.- __init__(initial_observation, transitions, action_gradient_stats=None)#
-
action_gradient_stats:
BatchedGradientNormStats|None= None#
- property alive_mask: Tensor#
Return rows active before each step, stopping after the first done.
- Returns:
Boolean tensor shaped
[time, num_envs].
- property final_observation: Tensor#
Return the observation after the final transition.
-
initial_observation:
Tensor#
- property num_steps: int#
Return the number of collected transitions.
- property observations: Tensor#
Stack the raw policy observations.
- Returns:
Tensor shaped
[time, num_envs, features].
- property rewards: Tensor#
Stack rewards as
[time, num_envs]without detaching them.
-
transitions:
tuple[DifferentiableTransition,...]#
- class embodichain.learning.rl.collector.DifferentiableTransition[source]#
Bases:
objectOne graph-preserving environment transition.
Methods:
__init__(observation, policy_output, reward, ...)Attributes:
Return the differentiable policy action.
Return the combined termination mask.
- __init__(observation, policy_output, reward, terminated, truncated, next_observation, info)#
- property action: Tensor#
Return the differentiable policy action.
- property done: Tensor#
Return the combined termination mask.
-
info:
dict[str,Any]#
-
next_observation:
Tensor#
-
observation:
Tensor#
-
policy_output:
TensorDict#
-
reward:
Tensor#
-
terminated:
Tensor#
-
truncated:
Tensor#
- class embodichain.learning.rl.collector.SyncCollector[source]#
Bases:
BaseCollectorSynchronously collect rollouts from a vectorized environment.
Methods:
Policies#
Policy implementations and registration live in embodichain.learning.rl.policies.
Runtime Reconstruction#
Shared environment and Policy construction for RL training and evaluation.
Classes:
An Environment and Policy reconstructed from one training configuration. |
Functions:
|
Build a simulator task and the Policy declared by its training config. |
|
Build a lightweight Environment and its configured Policy. |
- class embodichain.learning.rl.runtime.PolicyRuntime[source]#
Bases:
objectAn Environment and Policy reconstructed from one training configuration.
Methods:
__init__(env, policy, device, env_id[, ...])close()Close the Environment without terminating the current process.
Attributes:
- __init__(env, policy, device, env_id, env_cfg=None, gym_config=None, gym_config_path=None)#
-
device:
device#
-
env:
Any#
-
env_cfg:
Any|None= None#
-
env_id:
str#
-
gym_config:
dict[str,Any] |None= None#
-
gym_config_path:
Path|None= None#
-
policy:
Module#
- embodichain.learning.rl.runtime.build_gym_policy_runtime(config, *, device, num_envs, headless, renderer, gpu_id, seed=None, config_dir=None, profiler=None, simulation_device=None, trainer_events=())[source]#
Build a simulator task and the Policy declared by its training config.
- Parameters:
config (
dict[str,Any]) – Training configuration containing trainer and policy blocks.device (
device) – Policy tensor device.num_envs (
int|None) – Optional override for the number of environments.headless (
bool) – Whether to suppress the native window.renderer (
str|None) – Explicit renderer override; None preserves the task’s render configuration, including demand-based auto selection.gpu_id (
int) – Renderer GPU index when the simulation device has no CUDA index.seed (
int|None) – Optional environment seed override.config_dir (
str|Path|None) – Directory used to resolve the referenced task configuration.profiler (
ProfilerCfg|None) – Optional environment profiler configuration.simulation_device (
device|None) – Optional simulation device distinct from the policy.trainer_events (
Sequence[EventCfg]) – Active training and evaluation events, resolved before the first World so their cameras can reserve the process renderer.
- Return type:
- Returns:
The constructed environment, policy and resolved task configuration.
Training#
Functions:
|
Command-line interface for RL training. |
|
Parse command-line arguments. |
|
Run training from a config file path. |
- embodichain.learning.rl.train.cli(argv=None)[source]#
Command-line interface for RL training.
Parses CLI arguments and launches training from a config file.
Task packages are discovered (and init hooks executed) before training so that task environments registered in separate packages (e.g.
embodichain_tasks) are available tobuild_env. This mirrors therun_taskCLI.- Return type:
None
- embodichain.learning.rl.train.parse_args(argv=None)[source]#
Parse command-line arguments.
- Parameters:
argv (
Sequence[str] |None) – Arguments excluding the command name. Usessys.argvwhen omitted.- Return type:
Namespace- Returns:
Parsed training arguments.
- embodichain.learning.rl.train.train_from_config(config_path, distributed=None, *, profile=False, profile_output=None, resume=None, run=None, resume_scheduler='restore')[source]#
Run training from a config file path.
- Parameters:
config_path (
str) – Path to the training config file (.json, .yaml, or .yml).distributed (
bool|None) – If True, run multi-GPU distributed training. If None, use trainer.distributed from config.profile (
bool) – Enable gymEnvProfileron the training environment.profile_output (
str|None) – Optional JSON dump path for the profiling report.resume (
str|Path|None) – Checkpoint file, or latest/best selected from run.run (
str|Path|None) – Source run directory when resume selects latest/best.resume_scheduler (
str) – Restore the saved LR curve or restart the configured curve with optimizer momentum retained.
- Return type:
dict[str,object] |None- Returns:
The lightweight trainer summary, or
Nonefor simulator training.
Utilities#
RL helper utilities: algorithm config, optimizers, and observation helpers.
Classes:
Shared fields for RL algorithm configs. |
|
Optional LR scheduler. |
|
Policy optimizer configuration. |
Functions:
|
Fill |
|
Build a scheduler, or |
|
|
|
|
|
|
|
Convert an environment observation mapping into a TensorDict. |
Flatten a hierarchical observation TensorDict into a 2D tensor. |
|
|
Flatten selected observation groups in the configured order. |
- class embodichain.learning.rl.utils.AlgorithmCfg[source]#
Bases:
objectShared fields for RL algorithm configs.
Methods:
__init__([device, optimizer, lr_scheduler, ...])copy(**kwargs)Return a new object replacing specified fields with new values.
replace(**kwargs)Return a new object replacing specified fields with new values.
to_dict()Convert an object into dictionary recursively.
validate([prefix])Check the validity of configclass object.
Attributes:
- __init__(device=<factory>, optimizer=<factory>, lr_scheduler=<factory>, batch_size=<factory>, gamma=<factory>, gae_lambda=<factory>, max_grad_norm=<factory>)#
-
batch_size:
int#
- copy(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
-
device:
str#
-
gae_lambda:
float#
-
gamma:
float#
-
lr_scheduler:
LRSchedulerCfg#
-
max_grad_norm:
float#
-
optimizer:
OptimizerCfg#
- replace(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- to_dict()#
Convert an object into dictionary recursively.
Note
Ignores all names starting with “__” (i.e. built-in methods).
- Parameters:
obj (
object) – An instance of a class to convert.- Raises:
ValueError – When input argument is not an object.
- Return type:
dict[str,Any]- Returns:
Converted dictionary mapping.
- validate(prefix='')#
Check the validity of configclass object.
This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.
- Parameters:
obj (
object) – The object to check.prefix (
str) – The prefix to add to the missing fields. Defaults to ‘’.
- Return type:
list[str]- Returns:
A list of missing fields.
- Raises:
TypeError – When the object is not a valid configuration object.
- class embodichain.learning.rl.utils.LRSchedulerCfg[source]#
Bases:
objectOptional LR scheduler.
name=Nonedisables scheduling.Horizon keys (
total_iters/T_max) may be omitted and bound later byBaseAlgorithm.bind_schedule.Methods:
__init__([name, kwargs])copy(**kwargs)Return a new object replacing specified fields with new values.
replace(**kwargs)Return a new object replacing specified fields with new values.
to_dict()Convert an object into dictionary recursively.
validate([prefix])Check the validity of configclass object.
Attributes:
- __init__(name=<factory>, kwargs=<factory>)#
- copy(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
-
kwargs:
dict[str,Any]#
-
name:
str|None#
- replace(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- to_dict()#
Convert an object into dictionary recursively.
Note
Ignores all names starting with “__” (i.e. built-in methods).
- Parameters:
obj (
object) – An instance of a class to convert.- Raises:
ValueError – When input argument is not an object.
- Return type:
dict[str,Any]- Returns:
Converted dictionary mapping.
- validate(prefix='')#
Check the validity of configclass object.
This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.
- Parameters:
obj (
object) – The object to check.prefix (
str) – The prefix to add to the missing fields. Defaults to ‘’.
- Return type:
list[str]- Returns:
A list of missing fields.
- Raises:
TypeError – When the object is not a valid configuration object.
- class embodichain.learning.rl.utils.OptimizerCfg[source]#
Bases:
objectPolicy optimizer configuration.
Methods:
__init__([name, learning_rate, kwargs])copy(**kwargs)Return a new object replacing specified fields with new values.
replace(**kwargs)Return a new object replacing specified fields with new values.
to_dict()Convert an object into dictionary recursively.
validate([prefix])Check the validity of configclass object.
Attributes:
- __init__(name=<factory>, learning_rate=<factory>, kwargs=<factory>)#
- copy(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
-
kwargs:
dict[str,Any]#
-
learning_rate:
float#
-
name:
str#
- replace(**kwargs)#
Return a new object replacing specified fields with new values.
This is especially useful for frozen classes. Example usage:
@configclass(frozen=True) class C: x: int y: int c = C(1, 2) c1 = c.replace(x=3) assert c1.x == 3 and c1.y == 2
- Parameters:
obj (
object) – The object to replace.**kwargs – The fields to replace and their new values.
- Return type:
object- Returns:
The new object.
- to_dict()#
Convert an object into dictionary recursively.
Note
Ignores all names starting with “__” (i.e. built-in methods).
- Parameters:
obj (
object) – An instance of a class to convert.- Raises:
ValueError – When input argument is not an object.
- Return type:
dict[str,Any]- Returns:
Converted dictionary mapping.
- validate(prefix='')#
Check the validity of configclass object.
This function checks if the object is a valid configclass object. A valid configclass object contains no MISSING entries.
- Parameters:
obj (
object) – The object to check.prefix (
str) – The prefix to add to the missing fields. Defaults to ‘’.
- Return type:
list[str]- Returns:
A list of missing fields.
- Raises:
TypeError – When the object is not a valid configuration object.
- embodichain.learning.rl.utils.bind_scheduler_horizon(cfg, total_updates)[source]#
Fill
total_iters/T_maxfrom the training update budget.- Return type:
- embodichain.learning.rl.utils.build_lr_scheduler(optimizer, cfg)[source]#
Build a scheduler, or
Nonewhennameis unset.- Return type:
LRScheduler|None
- embodichain.learning.rl.utils.dict_to_tensordict(obs_dict, device)[source]#
Convert an environment observation mapping into a TensorDict.
- Parameters:
obs_dict (
Tensor|TensorDict|Mapping[str,Any]) – Tensor or mapping returned byreset()orstep().device (
device|str) – Target device for the resulting TensorDict.
- Return type:
TensorDict- Returns:
Observation TensorDict moved onto the target device.
- embodichain.learning.rl.utils.flatten_dict_observation(obs)[source]#
Flatten a hierarchical observation TensorDict into a 2D tensor.
- Parameters:
obs (
TensorDict) – Observation TensorDict with batch dimension [num_envs].- Return type:
Tensor- Returns:
Flattened observation tensor of shape [num_envs, obs_dim].
- embodichain.learning.rl.utils.flatten_observation_groups(obs, groups)[source]#
Flatten selected observation groups in the configured order.
A group name selects one top-level TensorDict key. Dot-separated names may select nested keys, for example
"robot.qpos". WhengroupsisNone, every tensor is flattened usingflatten_dict_observation()for compatibility with existing tasks.- Parameters:
obs (
TensorDict) – Observation TensorDict with batch dimension[num_envs].groups (
Sequence[str] |None) – Observation group names consumed by one model.
- Return type:
Tensor- Returns:
Concatenated observation tensor with shape
[num_envs, obs_dim].- Raises:
ValueError – If
groupsis empty or a selected group has no tensors.KeyError – If a configured group is absent from
obs.