Unity-Technologies/ml-agents · error · TrainerConfigError

When using a recurrent network, memory size must be divisibl

Error message

When using a recurrent network, memory size must be divisible by 2.

What it means

ML-Agents raises this when the `memory_size` hyperparameter in trainer config is set to an even-but-invalid negative or zero is caught separately, but an odd memory_size is rejected here. Recurrent networks (LSTM) require the memory size to be divisible by 2 because the LSTM cell internally splits memory between hidden state and cell state per direction. Odd values cannot be halved into two equal state tensors, so the config is rejected at load time via the attrs validator `_check_valid_memory_size`.

Source

Thrown at ml-agents/mlagents/trainers/settings.py:131

    HYPER = "hyper"
    NONE = "none"


@attr.s(auto_attribs=True)
class NetworkSettings:
    @attr.s
    class MemorySettings:
        sequence_length: int = attr.ib(default=64)
        memory_size: int = attr.ib(default=128)

        @memory_size.validator
        def _check_valid_memory_size(self, attribute, value):
            if value <= 0:
                raise TrainerConfigError(
                    "When using a recurrent network, memory size must be greater than 0."
                )
            elif value % 2 != 0:
                raise TrainerConfigError(
                    "When using a recurrent network, memory size must be divisible by 2."
                )

    normalize: bool = False
    hidden_units: int = 128
    num_layers: int = 2
    vis_encode_type: EncoderType = EncoderType.SIMPLE
    memory: Optional[MemorySettings] = None
    goal_conditioning_type: ConditioningType = ConditioningType.HYPER
    deterministic: bool = parser.get_default("deterministic")


@attr.s(auto_attribs=True)
class BehavioralCloningSettings:
    demo_path: str
    steps: int = 0
    strength: float = 1.0
    samples_per_update: int = 0

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Round memory_size up to the next even number (e.g. 129 -> 130, or prefer 128/256).
  2. Set memory_size to 0 to disable recurrence entirely if LSTM is not needed.
  3. Use power-of-two values like 64, 128, 256 which are always valid.

Example fix

# before
network_settings:
  memory_size: 129

# after
network_settings:
  memory_size: 130
Defensive patterns

Strategy: validation

Validate before calling

memory_size = cfg['network_settings']['memory_size']
if memory_size % 2 != 0 or memory_size <= 0:
    raise ValueError(f'memory_size must be a positive even integer, got {memory_size}')

Type guard

def is_valid_memory_size(v) -> bool:
    return isinstance(v, int) and v > 0 and v % 2 == 0

Try / catch

from mlagents.trainers.exception import TrainerConfigError
try:
    load_trainer_config(path)
except TrainerConfigError as e:
    print(f'Invalid memory_size: {e}')

Prevention

When it happens

Trigger: Setting `memory_size` to any odd positive integer (e.g. 65, 129) in the `network_settings` block of a trainer YAML while using a recurrent network.

Common situations: Users copy a config and tweak memory_size to a 'round' odd number, or scale memory size up by a small increment (128 -> 129) without realizing the divisibility constraint for LSTM.

Related errors


AI-assisted analysis of Unity-Technologies/ml-agents@3ecb446f75 (2026-09-02). Data as JSON: /api/errors/85c09f68456df0b7. Report an issue: GitHub.