Curriculum Terms¶
Curriculum terms adapt the task while it trains: they widen command ranges, ramp reward weights and tighten tolerances, usually keyed off average episode length or success. The curriculum manager computes them only in training; at eval the curricula are frozen. The curricula guide covers sharing state between terms; the term catalog lists every parameter.
The base classes CurriculumTerm and CurriculumTermFuncWrapper are on the
managers page.
Episode-length tracking¶
Locomotion curricula (e.g. average-episode-length tracking).
Attributes¶
Classes¶
AverageEpisodeLengthTracker
¶
AverageEpisodeLengthTracker(env: RLEnvBase, options: CurriculumTermOptions)
Bases: CurriculumTerm
Track the running mean of episode length.
Maintains a single device-side scalar updated with an EMA whose effective
time-constant is num_compute_average_epl episodes' worth of resets at the
reference env count BASE_NUM_ENVS, scaled linearly with env.num_envs.
Other curriculum terms read the current estimate via
env.curriculum_manager.get_state(<this term's name>). The state dict
carries both average_episode_length and an is_primed flag — the
latter is False until at least one reset() call has actually fed
episode lengths into the EMA, so consumers can avoid acting on the
initial-zero estimate before any episode has finished.
Declare this term before any consumer in curriculum_options so the
consumer's compute() sees a fresh value on the same step. Declared
after, get_state raises and names the ordering rather than reading as
"no value yet".
| PARAMETER | DESCRIPTION |
|---|---|
num_compute_average_epl
|
Reference EMA window in number of resets, expressed at
|
Source code in eden/managers/terms/curricula/locomotion.py
Attributes¶
average_episode_length
instance-attribute
¶
Methods:¶
reset
¶
Source code in eden/managers/terms/curricula/locomotion.py
compute
¶
Reward weights¶
Reward-weight curricula (staged ramp-up, penalty scheduling).
Attributes¶
Classes¶
StageRewardWeightCurriculum
¶
StageRewardWeightCurriculum(env: RLEnvBase, options: CurriculumTermOptions)
Bases: CurriculumTerm
Curriculum that sets a reward term's weight at given training steps.
| PARAMETER | DESCRIPTION |
|---|---|
reward_term_name
|
The name of the reward term.
|
weight_stages
|
|
Source code in eden/managers/terms/curricula/rewards.py
Attributes¶
weight_stages
class-attribute
instance-attribute
¶
weight_stages: list[tuple[int, float]] = sorted(self.weight_stages, key=lambda x: x[0], reverse=True)
Methods:¶
build
¶
Source code in eden/managers/terms/curricula/rewards.py
compute
¶
Source code in eden/managers/terms/curricula/rewards.py
PenaltyCurriculum
¶
PenaltyCurriculum(env: RLEnvBase, options: CurriculumTermOptions)
Bases: CurriculumTerm
Curriculum that gradually scales reward weights for a set of reward terms.
Monitors average episode length and adjusts a scale factor applied to all targeted reward terms. When episodes are short (agent struggling), the scale decreases to ease penalties. When episodes are long (agent succeeding), the scale increases to enforce stricter behaviour.
The scale factor multiplies the configured weight of each term, so the
effective weight is configured_weight * scale.
Targets can be specified by name OR by tag — exactly one entry path must be
used per curriculum instance. Mixing the two would split intent across two
fields and make refactors error-prone (e.g. renaming a term forgets the
name-list, but the tag-list still matches). Prefer reward_term_tags when
the same curriculum should apply to a group of penalties whose roster may
grow (just tag new terms); use reward_term_names for explicit, audited
targets.
| PARAMETER | DESCRIPTION |
|---|---|
reward_term_names
|
Explicit names of reward terms to scale. Mutually exclusive with
|
reward_term_tags
|
Tags to match on
|
initial_scale
|
Starting scale factor. Default 0.1 (10% of configured weight).
|
min_scale
|
Minimum allowed scale. Default 0.0.
|
max_scale
|
Maximum allowed scale. Default 1.0.
|
level_up_threshold
|
Average episode length (in steps) above which the scale increases.
|
level_down_threshold
|
Average episode length (in steps) below which the scale decreases.
|
degree
|
Amount to adjust the scale per curriculum compute call.
|
num_episode_average
|
Number of most recent episode lengths to average over. Ignored when
|
tracker_name
|
Optional name of an
|
Source code in eden/managers/terms/curricula/rewards.py
Attributes¶
Methods:¶
build
¶
Resolve the targeted reward terms and install initial_scale on them.
The reward manager is built before the curricula (EnvBase._manager_order), so an
unknown reward_term_names entry raises at env construction rather than on the first
reset. Installing the scale here — rather than on whichever of reset() / compute()
runs first — is also what keeps the initial scale applied at eval:
CurriculumManager freezes both of those there, so a term that only ever installed its
starting level from one of them would grade an eval rollout at the unscaled configured
weights.
Source code in eden/managers/terms/curricula/rewards.py
reset
¶
Source code in eden/managers/terms/curricula/rewards.py
compute
¶
Source code in eden/managers/terms/curricula/rewards.py
Velocity commands¶
Velocity curriculum for progressive velocity range expansion.
Attributes¶
Classes¶
VelocityCommandCurriculum
¶
VelocityCommandCurriculum(env: RLEnvBase, options: CurriculumTermOptions)
Bases: CurriculumTerm
Curriculum that progressively expands velocity command ranges.
| PARAMETER | DESCRIPTION |
|---|---|
command_name
|
The name of the velocity command term in the command manager.
TYPE:
|
velocity_stages
|
Stages, in any order (sorted by |
Source code in eden/managers/terms/curricula/velocity.py
Attributes¶
velocity_stages
class-attribute
instance-attribute
¶
command_term
instance-attribute
¶
Methods:¶
compute
¶
Source code in eden/managers/terms/curricula/velocity.py
Motion tracking¶
Motion-tracking curricula (success-driven tolerance tightening).
Attributes¶
Classes¶
MotionBasePoseThresholdCurriculum
¶
MotionBasePoseThresholdCurriculum(env: EnvBase, options: _TermOptionsT)
Bases: CurriculumTerm
Tighten a :class:MotionBasePoseTrackingBreak gate as success rises.
ConTrack's "threshold curriculum": an EMA of the per-episode success rate linearly
interpolates the paired termination term's pos_threshold / rot_threshold from
their *_max (lenient) values to their *_min (tight) ones as the EMA moves
across [success_rate_low, success_rate_high]. An episode counts as a success when
it ends with the motion clip exhausted (validity[:, 0] false at reset time) rather
than via the pose gate.
This lives in a curriculum term rather than inside the termination term so it gets the
three things curriculum state needs and a termination term cannot provide:
CurriculumManager logs :meth:compute's return under Curriculum/<name>/*,
it freezes curricula at eval (eval_mode=True) so an eval rollout is
graded at a fixed tolerance, and the state has one obvious home if/when term
checkpointing lands (nothing calls state_dict() on manager terms today, so a
resumed run still restarts the EMA at 0 — i.e. at the lenient thresholds).
Declaration order matters only against other curriculum terms; the thresholds this
writes are consumed by the next step's termination_manager.compute().
| PARAMETER | DESCRIPTION |
|---|---|
termination_term_name
|
Name of the
|
entity_name
|
Entity whose motion-reference
|
pos_threshold_max
|
Position tolerance (m) at
|
rot_threshold_max
|
Orientation tolerance (rad) at
|
success_ema_alpha
|
Per-episode EMA rate. The update is applied once per reset batch with an
effective rate of
|
success_rate_low
|
EMA values at which the thresholds sit at
|
Source code in eden/managers/base.py
Attributes¶
termination_term_name
class-attribute
instance-attribute
¶
termination_term_name: str = 'object_pose_break'
Methods:¶
build
¶
Source code in eden/managers/terms/curricula/motion.py
reset
¶
reset(envs_idx: slice | Tensor | None = None) -> None
Source code in eden/managers/terms/curricula/motion.py
compute
¶
Source code in eden/managers/terms/curricula/motion.py
Functions:¶
Success Guided Sampling¶
Success Guided Sampling (SGS): choose each episode's reset configuration from its recent success rate.
Zhang et al., "A Balanced Data Diet: Addressing the Exploration Bottleneck in Mega-Scale RL for Robot
Control" (CoRL 2026, arXiv:2610.12465), Sec. 3.2 and Appendix B.2. A task owns a fixed set of N
reset configurations. SGS keeps the last history success/failure outcomes of every configuration,
scores each configuration's success rate p with a Beta-shaped kernel peaked at target, and draws
the next configuration of every resetting env from a softmax over those scores. Most episodes go to
configurations the policy solves sometimes; every configuration keeps a non-zero probability, so the
estimates of the ones it cannot solve yet (or has mastered) keep being refreshed.
The term is a :class:~eden.managers.resets.sampling.ResetConfigSampler: the RESET event that owns the
configuration set binds it and calls :meth:SuccessGuidedSampling.sample, because the RESET events run
before any manager's reset() (see :mod:eden.managers.resets.sampling). sample grades the episode
that just ended before it draws the next one -- the termination manager still holds the finished step's
verdicts then, since its own reset() comes later in the same walk.
Attributes¶
Classes¶
SuccessGuidedSampling
¶
SuccessGuidedSampling(env: EnvBase, options: _TermOptionsT)
Bases: CurriculumTerm, ResetConfigSampler
Draw each resetting env's reset configuration with probability peaked at a target success rate.
A reset event that owns a configuration set names this term (its sampler parameter), binds it to
the set size in its build() and calls :meth:sample from every reset. A term no reset event binds
fails env construction.
A configuration never graded reads p = 0, so before any outcome is in, sampling is uniform.
An outcome is recorded for an env when its episode ended: it is in the reset selection, the
termination manager has it done, and it ran at least one step. A success is the success_term
termination having fired on that last step. Not graded: an env's first spawn, an env.reset()
that cut an episode short, and an episode the simulator flagged as corrupt
(termination_manager.solver_errors) -- that one ended on the solver, not on the task. When more than
history envs finish one configuration in the same reset, a uniformly random history of them are
recorded.
At eval (env.training False) configurations are drawn uniformly and nothing is recorded:
evaluation grades the policy on the task distribution, not on the sampler's current emphasis.
The defaults are the paper's locomotion settings; it uses target=0.5, concentration=1.0,
floor=1e-4 for manipulation.
| ATTRIBUTE | DESCRIPTION |
|---|---|
success_term |
Termination term whose firing marks an episode a success (e.g.
TYPE:
|
history |
Outcomes kept per configuration (a ring buffer);
TYPE:
|
target |
Success rate the kernel peaks at, in [0, 1].
TYPE:
|
concentration |
Kernel sharpness
TYPE:
|
temperature |
Softmax temperature, effective value
TYPE:
|
floor |
TYPE:
|
Source code in eden/managers/base.py
Attributes¶
success_rate
property
¶
(num_configs,): mean of each configuration's recorded outcomes; 0 where none is recorded.
num_outcomes
property
¶
(num_configs,) long: outcomes recorded per configuration over the run (not capped at history).
probabilities
property
¶
(num_configs,): the distribution the next training reset draws from.
Methods:¶
build
¶
Source code in eden/managers/terms/curricula/success_guided.py
compute
¶
Publish the sampler's state; device tensors, so logging it costs no sync.
mean_success averages p over the configurations graded at least once;
frontier_frac is the share of the whole set with 0 < p < 1 -- solved sometimes, the
configurations SGS exists to find; sampling_ess_frac is the effective sample size of the
sampling distribution as a fraction of the set (1 = uniform).
Source code in eden/managers/terms/curricula/success_guided.py
Functions:¶
success_guided_probabilities
¶
success_guided_probabilities(success_rate: Tensor, *, target: float, concentration: float, temperature: float, floor: float) -> Tensor
Sampling probability of each configuration given its success rate (paper Eq. 1-2, Appendix B.2).
w = (p + eps)^(k t) * (1 - p + eps)^(k (1 - t)) -- the Beta(1 + k t, 1 + k (1 - t)) density in
mode-concentration form, up to a constant -- floored at eps; the logit is log(w + eps) and the
probabilities a softmax over the logits at temperature max(temperature, 1).