- 人工智能
- 强化学习
- 深度学习
- 机器学习
- 游戏开发
- 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.
导读
本指南围绕 Unity ML-Agents 提供的 PettingZoo 包装器展开,它把基于UnityEnvironment的 Unity 仿真环境封装为符合 PettingZoo 标准的 AEC(Agent Environment Cycle)与 Parallel 两种多智能体接口。你将掌握UnityAECEnv、UnityParallelEnv与PettingZooEnvFactory的完整 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.AECEnv与pettingzoo.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.py | PettingZooEnvFactory | 从环境注册表创建 Unity 环境并封装为 AEC 包装器 |
unity_aec_env.py | UnityAECEnv(UnityPettingzooBaseEnv, AECEnv) | PettingZoo AEC 接口(逐智能体轮转) |
unity_parallel_env.py | UnityParallelEnv(UnityPettingzooBaseEnv, ParallelEnv) | PettingZoo Parallel 接口(全体同时行动) |
unity_pettingzoo_base_env.py | UnityPettingzooBaseEnv | 共享基类: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:用于各智能体动作空间的随机种子;kwargs:UnityEnvironment类接受的任意参数(file_name除外)。
底层行为(见 pettingzoo_env_factory.py):
- 若未显式传入
side_channels,会自动补充三个默认侧信道:EngineConfigurationChannel、EnvironmentParametersChannel、StatsSideChannel; - 若未提供
base_port,则从 6000 开始逐个尝试端口,直到找到一个未被占用的端口(捕获UnityWorkerInUseException后端口自增); - 通过
default_registry[env_id].make(**kwargs)从注册表创建环境,最后返回UnityAECEnv包装器。
这里的default_registry是UnityEnvRegistry单例(见 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)完成三件事:
- 把传入动作转换为 numpy 数组并校验
current_action_space.contains(action),非法动作抛出error.Error; - 按空间类型转换为底层
ActionTuple(离散标量 reshape 为(1, 1)、连续动作直接作为continuous分量); - 若智能体已终止/截断,则从存活列表与各状态字典中移除;否则把动作写入
_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>]访问(例如EngineConfigurationChannel、EnvironmentParametersChannel、StatsSideChannel),用于在训练循环中收发自定义数据。
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 中额外写入interrupted、behavior_name、group_id、group_reward字段; - 观测若为多观测则保留列表,单观测直接取出;
- 若
DecisionSteps.action_mask存在,观测会附上action_mask(离散动作遮蔽信息)。
这一"interrupted → truncation"的语义在单元测试 test_pettingzoo_wrapper.py 中被显式断言,是该包装器对齐 PettingZoo 规范的关键细节。
九、使用注意事项(重要)
根据官方文档 Python-PettingZoo-API.md 与源码实现,使用时需注意以下四点:
- AEC 与 Parallel 双支持:包装器同时实现 PettingZoo 的 AEC 与 Parallel 两套 API,按需选择;
- AEC 底层是"攒批步进":
UnityAECEnv并不会在每次env.step(action)时真的步进环境,而是先存储动作,直到当前步所有请求动作的智能体都被分配动作后才批量提交给 Unity。这是出于性能考虑——Unity 与 Python 之间的通信在数据批量发送时效率更高; - 瞬时奖励语义有差异:由于 AEC 动作是延迟应用的,某些 API 组件可能表现异常。例如
env.reward应返回该步的瞬时奖励,但真实奖励要等实际环境步进后才可用。建议遵循 API 定义训练——从env.last()获取奖励,而不是env.reward,底层机制不影响训练结果; - 环境自动重置:当环境完成一个 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.env | env(seed=None, **kwargs) -> UnityAECEnv | 从注册表创建并包装环境;自动补充默认侧信道、自动探测空闲端口 |
UnityAECEnv.step | step(action) -> None | 设置当前智能体动作,攒批后步进 |
UnityAECEnv.observe | observe(agent_id) | 返回智能体的 (obs, 累计奖励, termination, truncation, info) |
UnityAECEnv.last | last(observe=True) | 返回当前轮转智能体的上述五元组 |
UnityParallelEnv.reset | reset(seed=None, options=None) -> (obs, infos) | 重置并返回全体观测与 info |
UnityParallelEnv.step | step(actions: Dict) -> (obs, rewards, terminations, truncations, infos) | 全体动作同时步进 |
UnityPettingzooBaseEnv.side_channel | 属性 | 按类名访问侧信道 |
UnityPettingzooBaseEnv.render | render() | 不支持(空实现) |
UnityPettingzooBaseEnv.close | close() -> 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.
相关推荐
Unity ML-Agents 智能体(Agent)设计实战指南:观测、动作、奖励与多智能体协作
Unity ML Agents 智能体(Agent)设计实战指南:观测、动作、奖励与多智能体协作 本篇技术指南以 Unity ML Agents 工具包的官方文
人工智能强化学习深度学习机器学习游戏开发AI 应用Unity ML-Agents 低层 Python API(LLAPI)实战指南:用 mlagents_envs 直接控制 Unity 强化学习环境
Unity ML Agents 低层 Python API(LLAPI)实战指南:用 mlagents_envs 直接控制 Unity 强化学习环境 本文是 U
人工智能强化学习深度学习机器学习游戏开发AI 应用ComfyUI-LTXVideo终极指南:5个技巧解决LTX-2视频生成技术难题
ComfyUI LTXVideo终极指南:5个技巧解决LTX 2视频生成技术难题 ComfyUI LTXVideo作为LTX 2视频生成模型在ComfyUI中的
人工智能大模型AI 应用媒体生成本地部署
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考