ML-Agents PettingZoo 包装器实战指南:用 AEC / Parallel 多智能体 API 驱动 Unity 环境
2026/9/20 15:25:27 网站建设 项目流程
  • 人工智能
  • 强化学习
  • 深度学习
  • 机器学习
  • 游戏开发
  • AI 应用

【免费下载链接】ml-agents

The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.

项目地址:https://gitcode.com/gh_mirrors/ml/ml-agents
点击查看免费下载

导读

本指南围绕 Unity ML-Agents 提供的 PettingZoo 包装器展开,它把基于UnityEnvironment的 Unity 仿真环境封装为符合 PettingZoo 标准的 AEC(Agent Environment Cycle)与 Parallel 两种多智能体接口。你将掌握UnityAECEnvUnityParallelEnvPettingZooEnvFactory的完整 API、与底层BaseEnv的对应关系、批量步进机制以及真实可运行的训练循环写法,从而把 Unity 多智能体场景无缝接入 PettingZoo 生态(如 SuperSuit、稳定基线等工具链)。

一、背景:为什么需要 PettingZoo 包装器

随着多智能体强化学习(MARL)对 gym 风格 API 的需求增长,ML-Agents 提供了围绕 PettingZoo API 的包装器。它建立在UnityEnvironment类之上——这是通过 Python 与 Unity 环境交互的默认方式。包装器的目标非常明确:让 Unity 环境中多个行为(Behavior)各异、甚至同一行为下多个智能体的多智能体场景,能够以标准的 PettingZoo 接口被外部训练框架消费,而不必直接处理底层的DecisionSteps/TerminalSteps批次数据。

在 ML-Agents 中,一个行为(BehaviorName)把"观测与动作空间相同、期望行为相近"的一批智能体归为一组,数据按批次传输(见 base_env.py 的模块说明)。PettingZoo 包装器正是把这种"按行为分组的批处理世界"翻译成"按智能体逐一交互的世界"。

二、安装与前置条件

PettingZoo 包装器属于mlagents_envs包,安装mlagents_envs时即包含该包装器:

pip install mlagents_envs

同时需要安装pettingzoo依赖(包装器直接继承pettingzoo.AECEnvpettingzoo.ParallelEnv)。完整安装说明可参考 ml-agents-envs/README.md。

仓库自带一个端到端的 Colab 示例 Colab_PettingZoo.ipynb,演示了安装、基本用法,以及基于Strikers vs Goalie(一个包含多个不同行为名的多智能体环境,详细介绍见 Learning-Environment-Examples.md)的完整示例,是快速上手的推荐起点。

三、架构总览:从 UnityEnvironment 到 PettingZoo

包装器整体位于 ml-agents-envs/mlagents_envs/envs/ 目录,核心包含四个模块:

模块职责
pettingzoo_env_factory.pyPettingZooEnvFactory从环境注册表创建 Unity 环境并封装为 AEC 包装器
unity_aec_env.pyUnityAECEnv(UnityPettingzooBaseEnv, AECEnv)PettingZoo AEC 接口(逐智能体轮转)
unity_parallel_env.pyUnityParallelEnv(UnityPettingzooBaseEnv, ParallelEnv)PettingZoo Parallel 接口(全体同时行动)
unity_pettingzoo_base_env.pyUnityPettingzooBaseEnv共享基类:space 映射、动作处理、底层步进

继承关系与数据流如下:

UnityEnvironment (BaseEnv) │ 行为批数据 DecisionSteps / TerminalSteps ▼ UnityPettingzooBaseEnv ── 展开为 {agent_id: obs/reward/...} 字典 ├── UnityAECEnv(AEC,逐智能体 step) └── UnityParallelEnv(Parallel,全体 step)

构造包装器时,基类会在__init__中做一次环境预步进(若behavior_specs为空则主动env.step()),以便把行为信息发送过来,进而建立观测空间与动作空间映射(见 unity_pettingzoo_base_env.py)。

四、环境工厂:PettingZooEnvFactory

env 方法

class PettingZooEnvFactory: def __init__(self, env_id: str) -> None: ... def env( self, seed: Optional[int] = None, **kwargs: Union[List, int, bool, None] ) -> UnityAECEnv: ...

参数说明:

  • seed:用于各智能体动作空间的随机种子;
  • kwargsUnityEnvironment类接受的任意参数(file_name除外)。

底层行为(见 pettingzoo_env_factory.py):

  1. 若未显式传入side_channels,会自动补充三个默认侧信道:EngineConfigurationChannelEnvironmentParametersChannelStatsSideChannel
  2. 若未提供base_port,则从 6000 开始逐个尝试端口,直到找到一个未被占用的端口(捕获UnityWorkerInUseException后端口自增);
  3. 通过default_registry[env_id].make(**kwargs)从注册表创建环境,最后返回UnityAECEnv包装器。

这里的default_registryUnityEnvRegistry单例(见 unity_env_registry.py),它维护了一批无需安装 Unity 编辑器即可直接启动的环境(如StrikersVsGoalie),支持从本地或远程 manifest(YAML)懒加载注册条目,并通过registry[<identifier>].make()启动对应可执行文件。mlagents_envs.envs包在导入时会遍历注册表,为每个已注册环境动态绑定一个PettingZooEnvFactory实例(见 ml-agents-envs/mlagents_envs/envs/init.py),因此可以直接以mlagents_envs.envs.<env_name>的方式使用:

import mlagents_envs.envs env = mlagents_envs.envs.StrikersVsGoalie.env()

五、AEC 接口:UnityAECEnv

类定义与初始化

class UnityAECEnv(UnityPettingzooBaseEnv, AECEnv): def __init__(self, env: BaseEnv, seed: Optional[int] = None):
  • env:被包装的UnityEnvironment(或任意BaseEnv);
  • seed:用于动作空间采样的随机种子。

step(action)

def step(self, action: Any) -> None:

设置当前活跃智能体的动作,并获取下一个智能体的观测、奖励、终止、截断与信息。这是 AEC 的核心——每次调用只处理一个智能体。

关键实现(见 unity_aec_env.py):

  • _live_agents为空(即尚未 reset),会抛出 gymnasium 的error.Error("You must reset the environment before you can perform a step")
  • 将动作通过_process_action存入当前动作缓冲,然后推进_agent_index,并清零所有智能体的瞬时奖励
  • _agent_index超过智能体总数时,才真正调用_step()把缓冲中的全部动作一次性交给底层 Unity 环境步进。

observe(agent_id) 与 last()

def observe(self, agent_id): ... def last(self, observe=True):

observe返回指定智能体的五元组:(observation, cumulative_reward, termination, truncation, info)last()observe的封装,返回当前轮转智能体(由self.agent_selection指定,即_agent_index对应的智能体)的同一组数据;observe=False时观测部分返回None

agent_selection

@property def agent_selection(self):

若没有存活智能体,返回_agents[0](用于处理最后一个智能体刚刚结束的局面);否则返回当前索引对应的智能体。

典型 AEC 交互循环

from mlagents_envs.environment import UnityEnvironment from mlagents_envs.envs.unity_aec_env import UnityAECEnv unity_env = UnityEnvironment("StrikersVsGoalie") env = UnityAECEnv(unity_env) env.reset() for agent in env.agent_iter(): observation, reward, termination, truncation, info = env.last() action = policy(observation, agent) env.step(action)

这个循环与 PettingZoo 官方 AEC API 完全一致,可以直接替换任何标准 AEC 环境。

六、Parallel 接口:UnityParallelEnv

class UnityParallelEnv(UnityPettingzooBaseEnv, ParallelEnv): def __init__(self, env: BaseEnv, seed: Optional[int] = None):

Parallel API 面向"所有智能体同时决策"的场景,接口更贴近传统 RL batch 思维:

  • reset(seed=None, options=None) -> Tuple[Dict[str, Any], Dict[str, Dict]]:重置环境,返回(observations, infos)两个以agent_id为键的字典;
  • step(actions: Dict[str, Any]) -> Tuple:接收{agent_id: action}字典,一次性处理全部智能体的动作并步进环境,返回(observations, rewards, terminations, truncations, infos)五个字典(实现见 unity_parallel_env.py)。

Parallel 模式下每次step都会真正驱动底层环境前进,动作无需像 AEC 那样攒批。

七、共享基类:UnityPettingzooBaseEnv

基类封装了 AEC 与 Parallel 共用的逻辑,是理解整个包装器的关键(见 unity_pettingzoo_base_env.py)。

观测与动作空间

@property def observation_spaces(self) -> Dict[str, spaces.Space]: ... def observation_space(self, agent: str) -> Optional[spaces.Space]: ... @property def action_spaces(self) -> Dict[str, spaces.Space]: ... def action_space(self, agent: str) -> Optional[spaces.Space]: ...
  • 观测空间:每个ObservationSpec被映射为spaces.Box(low=-inf, high=inf, shape=spec.shape, dtype=np.float32);若一个行为有多个观测,则包装为spaces.Tuple
  • 动作空间:根据ActionSpec生成,规则如下(源码第 112-145 行):
动作类型生成的 gymnasium 空间
仅单个离散分支(discrete_size == 1且无连续)spaces.Discrete(branch_size)
多个离散分支(无连续)spaces.MultiDiscrete(discrete_branches)
仅连续动作spaces.Box(-1, 1, (continuous_size,), dtype=np.float32)
连续 + 离散混合spaces.Tuple((c_space, d_space))

动作空间在__init__中创建并(在提供seed时)播种;reset(seed=...)重新播种已有空间,保证可复现采样(对应测试见下文第八节)。

动作处理与批量步进

_process_action(current_agent, action)完成三件事:

  1. 把传入动作转换为 numpy 数组并校验current_action_space.contains(action),非法动作抛出error.Error
  2. 按空间类型转换为底层ActionTuple(离散标量 reshape 为(1, 1)、连续动作直接作为continuous分量);
  3. 若智能体已终止/截断,则从存活列表与各状态字典中移除;否则把动作写入_current_action缓冲中该智能体对应的行。

_step()则是真正的"攒批提交":遍历_current_action,为每个行为调用_env.set_actions(behavior_name, actions),随后_env.step()推进仿真,再对各行为调用_batch_update读取新的DecisionSteps/TerminalSteps并刷新所有智能体状态。

side_channel 属性

@property def side_channel(self) -> Dict[str, Any]:

返回环境侧信道字典,按侧信道类名为键,可通过env.side_channel[<name-of-channel>]访问(例如EngineConfigurationChannelEnvironmentParametersChannelStatsSideChannel),用于在训练循环中收发自定义数据。

reset / render / close

def reset(self, seed: Optional[int] = None, options: Optional[Dict] = None) -> Any: ... def render(self): ... # NOT SUPPORTED(空实现 pass) def close(self) -> None: ...
  • reset:重置所有状态字典、清空possible_agents,调用底层_env.reset(),然后重新拉取各行为数据;
  • render不支持(占位实现,pass);
  • close:关闭底层环境并把_env置为None;基类还注册了atexit.register(self.close)__del__,确保进程退出时资源被释放。

八、智能体 ID 编码与批次解包

包装器把"行为 + 批内序号"编码为字符串形式的agent_id,编码规则在 env_helpers.py 中:

def _behavior_to_agent_id(behavior_name: str, unique_id: int) -> str: return f"{behavior_name}?agent_id={unique_id}"

因此智能体 ID 形如StrikersVsGoalie?agent_id=0_agent_id_to_behavior通过split("?agent_id=")反向还原行为名。_unwrap_batch_steps则把一对(DecisionSteps, TerminalSteps)解包为字典形式的观测、奖励、终止、截断、info 与 id 映射,其中:

  • termination 与 truncation 的区分TerminalSteps.interrupted为准:interrupted=True记为截断(truncation),否则记为终止(termination),并在 info 中额外写入interruptedbehavior_namegroup_idgroup_reward字段;
  • 观测若为多观测则保留列表,单观测直接取出;
  • DecisionSteps.action_mask存在,观测会附上action_mask(离散动作遮蔽信息)。

这一"interrupted → truncation"的语义在单元测试 test_pettingzoo_wrapper.py 中被显式断言,是该包装器对齐 PettingZoo 规范的关键细节。

九、使用注意事项(重要)

根据官方文档 Python-PettingZoo-API.md 与源码实现,使用时需注意以下四点:

  1. AEC 与 Parallel 双支持:包装器同时实现 PettingZoo 的 AEC 与 Parallel 两套 API,按需选择;
  2. AEC 底层是"攒批步进"UnityAECEnv并不会在每次env.step(action)时真的步进环境,而是先存储动作,直到当前步所有请求动作的智能体都被分配动作后才批量提交给 Unity。这是出于性能考虑——Unity 与 Python 之间的通信在数据批量发送时效率更高;
  3. 瞬时奖励语义有差异:由于 AEC 动作是延迟应用的,某些 API 组件可能表现异常。例如env.reward应返回该步的瞬时奖励,但真实奖励要等实际环境步进后才可用。建议遵循 API 定义训练——从env.last()获取奖励,而不是env.reward,底层机制不影响训练结果;
  4. 环境自动重置:当环境完成一个 episode 后会自动重置,因此env.agent_iter(max_step)会一直运行直到达到指定的最大步数(默认2**63)。除初始化时外,无需手动调用env.reset()

十、测试验证

仓库通过 PettingZoo 官方 API 一致性测试保证包装器行为正确(见 test_pettingzoo_wrapper.py):

  • test_single_agent_aec/test_multi_agent_aec:分别用单智能体与双智能体模拟环境跑pettingzoo.test.api_test,各 100 个周期;
  • test_single_agent_parallel/test_multi_agent_parallel:用pettingzoo.test.parallel_api_test验证 Parallel 包装器;
  • test_reset_seed_reseeds_action_spaces:验证reset(seed=...)会真正重新播种既有动作空间,保证采样可复现;
  • test_unwrap_batch_steps_terminated_truncated:验证interrupted与 termination/truncation 的映射语义。

这些测试同时表明:包装器可以接收任何实现了BaseEnv接口的对象(包括测试用的SimpleEnvironment/MultiAgentEnvironment模拟环境),而不限于真实的UnityEnvironment,极大方便了算法调试与单元测试。

十一、快速参考:API 一览

类 / 方法签名说明
PettingZooEnvFactory.envenv(seed=None, **kwargs) -> UnityAECEnv从注册表创建并包装环境;自动补充默认侧信道、自动探测空闲端口
UnityAECEnv.stepstep(action) -> None设置当前智能体动作,攒批后步进
UnityAECEnv.observeobserve(agent_id)返回智能体的 (obs, 累计奖励, termination, truncation, info)
UnityAECEnv.lastlast(observe=True)返回当前轮转智能体的上述五元组
UnityParallelEnv.resetreset(seed=None, options=None) -> (obs, infos)重置并返回全体观测与 info
UnityParallelEnv.stepstep(actions: Dict) -> (obs, rewards, terminations, truncations, infos)全体动作同时步进
UnityPettingzooBaseEnv.side_channel属性按类名访问侧信道
UnityPettingzooBaseEnv.renderrender()不支持(空实现)
UnityPettingzooBaseEnv.closeclose() -> None关闭环境

更完整的类与签名定义可查阅 Python-PettingZoo-API-Documentation.md。

结语

ML-Agents 的 PettingZoo 包装器在保持底层UnityEnvironment批处理性能优势的同时,为多智能体场景提供了标准化的 AEC / Parallel 接口。理解"智能体 ID 编码 → 空间映射 → 攒批步进"这条链路,你就能自如地把任意 Unity 多智能体环境接入 PettingZoo 生态,直接复用社区中大量基于该 API 开发的 MARL 算法与工具。

  • 人工智能
  • 强化学习
  • 深度学习
  • 机器学习
  • 游戏开发
  • AI 应用

【免费下载链接】ml-agents

The Unity Machine Learning Agents Toolkit (ML-Agents) is an open-source project that enables games and simulations to serve as environments for training intelligent agents using deep reinforcement learning and imitation learning.

项目地址:https://gitcode.com/gh_mirrors/ml/ml-agents
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询