Unity-Technologies/ml-agents · error · UnityTrainerException

SAC does not support SharedActorCritic

Error message

SAC does not support SharedActorCritic

What it means

UnityTrainerException raised in the SAC optimizer's __init__ when the policy's actor is a SharedActorCritic network. SAC builds its own separate ValueNetwork critic and therefore cannot use the shared actor-critic architecture supported by PPO. The check runs at optimizer construction, so the run fails immediately at startup.

Source

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

            return q1_out, q2_out

    class TargetEntropy(NamedTuple):

        discrete: List[float] = []  # One per branch
        continuous: float = 0.0

    class LogEntCoef(nn.Module):
        def __init__(self, discrete, continuous):
            super().__init__()
            self.discrete = discrete
            self.continuous = continuous

    def __init__(self, policy: TorchPolicy, trainer_settings: TrainerSettings):
        super().__init__(policy, trainer_settings)
        reward_signal_configs = trainer_settings.reward_signals
        reward_signal_names = [key.value for key, _ in reward_signal_configs.items()]
        if isinstance(policy.actor, SharedActorCritic):
            raise UnityTrainerException("SAC does not support SharedActorCritic")
        self._critic = ValueNetwork(
            reward_signal_names,
            policy.behavior_spec.observation_specs,
            policy.network_settings,
        )
        hyperparameters: SACSettings = cast(
            SACSettings, trainer_settings.hyperparameters
        )

        self.tau = hyperparameters.tau
        self.init_entcoef = hyperparameters.init_entcoef

        self.policy = policy
        policy_network_settings = policy.network_settings

        self.tau = hyperparameters.tau
        self.burn_in_ratio = 0.0

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Set network_settings.shared_critic to false in your YAML, or remove the shared_critic key (defaults to false).
  2. Switch the trainer to PPO/POCA if you specifically want a shared actor-critic network.
  3. Keep SAC with its default separate critic; tune SAC via separate hyperparameters (buffer_size, learning_rate) instead.

Example fix

# before (SAC YAML)
network_settings:
  shared_critic: true
# after
network_settings:
  shared_critic: false
Defensive patterns

Strategy: validation

Validate before calling

config = yaml.safe_load(open("config.yaml"))
ns = config["behavior"].get("network_settings", {})
if config["behavior"]["trainer_type"] == "sac" and ns.get("shared_critic", False):
    raise ValueError("shared_critic is not supported by SAC; set it to false")

Type guard

def sac_config_is_valid(behavior_config: dict) -> bool:
    if behavior_config.get("trainer_type") != "sac":
        return True
    return not behavior_config.get("network_settings", {}).get("shared_critic", False)

Try / catch

from mlagents.trainers.exception import UnityTrainerException
try:
    optimizer = SACTorchOptimizer(policy, trainer_settings)
except UnityTrainerException:
    trainer_settings.network_settings.shared_critic = False
    optimizer = SACTorchOptimizer(policy, trainer_settings)

Prevention

When it happens

Trigger: Configuring shared_critic=true (SharedActorCritic actor) in network_settings while using the SAC trainer, e.g.: behavior: network_settings: shared_critic: true with trainer_type: sac.

Common situations: Copying a PPO config into an SAC run without removing shared_critic; experimenting with memory/shared networks and not realizing SAC requires a separate critic.

Related errors


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