把多个智能体丢进同一个环境里各自学习,听起来很美好,但真正跑过实验的人都知道,训练曲线经常是发散的。问题的根源并不在算法本身实现有误,而是多智能体环境固有的非平稳性:从任何一个智能体的视角看,其他智能体也在不断更新策略,环境的状态转移和奖励分布因此持续变化,这直接打破了单智能体强化学习所依赖的平稳环境假设。CTDE(Centralized Training with Decentralized Execution,集中式训练分布式执行)正是针对这一困境提出的训练范式,也是目前MADDPG、QMIX、MAPPO等主流多智能体算法的共同基石。

为什么多智能体环境是非平稳的
先从问题的本质说起。单智能体强化学习建立在马尔可夫决策过程(MDP)之上,其核心假设是环境的状态转移概率P(s'|s,a)和奖励函数在训练过程中保持不变。智能体只要策略足够好,就能把环境当作一个固定的对手来博弈,最终收敛到最优策略。
但在多智能体场景下,这个假设彻底失效。假设环境中有N个智能体,每个智能体i观测到的转移实际上依赖于所有智能体的联合动作a=(a1,a2,...,aN)。当智能体2在第100轮更新了策略,智能体1面对的“环境”就变了。也就是说,智能体1辛辛苦苦学到的Q值估计,在其他伙伴的策略更新之后可能瞬间过时。这种“移动的靶子”使得经验回放池中的旧数据价值大打折扣,训练过程极易震荡甚至发散。
另一个连带问题是维度灾难与信用分配。联合动作空间随智能体数量呈指数级增长,如果直接把多智能体问题当成一个大动作空间的单智能体问题来解,探索效率会急剧下降。同时,团队奖励是所有智能体行为的叠加结果,如何判断哪个智能体对最终结果贡献大,也就是信用分配问题,同样让学习变得困难。
CTDE的核心思想:训练时看全局,执行时靠局部
CTDE的解决思路非常直接:既然非平稳性来源于训练时看不到其他智能体的策略变化,那就在训练阶段把全局信息集中起来用;既然实际部署时往往不允许中心化控制(通信受限、延迟高、单点故障风险),那就在执行阶段让每个智能体只依赖本地观测独立决策。
具体拆开来看,集中式训练包含两个层面。第一是信息层面,中心化的评论家(Critic)可以访问全局状态、所有智能体的观测甚至所有智能体的动作,从而对每个智能体的策略给出稳定、准确的价值评估。因为评估时看到了完整信息,其他智能体策略变化带来的不确定性就从“环境噪声”变成了“已知条件”,非平稳问题被显著缓解。第二是数据层面,多智能体之间可以共享经验、共享参数,提升样本效率。
分布式执行则要求每个智能体的执行完全本地化:策略网络只输入自己的观测,不需要运行时通信,也不依赖中心服务器。这一点在机器人集群、自动驾驶车队等真实场景中尤为关键。用公式表达MADDPG中的中心化评论家,大致是如下形式:
import torch
import torch.nn as nn
import torch.nn.functional as F
class CentralizedCritic(nn.Module):
# 中心化评论家:输入所有智能体的观测与动作
def __init__(self, obs_dim, act_dim, num_agents):
super().__init__()
# 输入为 N 个智能体的 (obs + act) 拼接
self.fc1 = nn.Linear(num_agents * (obs_dim + act_dim), 256)
self.fc2 = nn.Linear(256, 256)
self.q_out = nn.Linear(256, 1) # 输出联合动作的 Q 值
def forward(self, obs_all, act_all):
x = torch.cat([obs_all, act_all], dim=-1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
return self.q_out(x)
训练时,每个智能体的Actor根据本地观测生成动作,而Critic在更新时拿到了所有智能体的观测和动作,因此能对当前策略组合做出稳定评估。执行时只部署Actor,Critic被丢弃。这就是“训练集中、执行分布”的字面含义。
两种典型实现路线:中心化评论家与值函数分解
CTDE并不是某个具体算法,而是一类训练范式,目前主要有两条实现路线。第一条是中心化评论家路线,代表算法是MADDPG和MAPPO。MADDPG为每个智能体维护一个确定性行动者网络和一个中心化评论家网络,评论家以所有智能体的观测和动作为输入,输出该智能体在联合动作下的Q值。由于评估时把其他智能体的动作当作已知量,梯度估计的方差大幅降低。
第二条是值函数分解路线,代表算法是VDN和QMIX,主要面向完全协作场景下的值函数类方法。这类方法的核心问题是:训练时用全局Q函数评估,执行时每个智能体要独立选动作,那全局Q值和每个智能体的个体Q值之间如何对齐?VDN的做法最简单粗暴,直接把所有智能体的个体Q值相加来近似全局Q值。QMIX则更精细,用一个混合网络(Mixing Network)非线性地组合个体Q值,并借助单调性约束保证argmax全局Q值等价于每个智能体各自argmax个体Q值。
import torch
import torch.nn as nn
class QMixer(nn.Module):
# QMIX 混合网络:用超网络生成权重,保证单调性
def __init__(self, num_agents, state_dim, embed_dim=64):
super().__init__()
self.num_agents = num_agents
# 状态超网络,生成第一层权重
self.hyper_w = nn.Sequential(
nn.Linear(state_dim, embed_dim),
nn.ReLU(),
nn.Linear(embed_dim, num_agents * embed_dim)
)
self.hyper_b = nn.Linear(state_dim, embed_dim)
# 最终标量偏置,必须非负,用绝对值保证
self.v = nn.Sequential(
nn.Linear(state_dim, embed_dim),
nn.ReLU(),
nn.Linear(embed_dim, 1)
)
def forward(self, agent_qs, state):
# agent_qs: [batch, num_agents]
w = torch.abs(self.hyper_w(state)).view(-1, self.num_agents, embed_dim if False else 1)
# 取绝对值保证权重非负,从而保证 Qtot 对每个 Qi 单调递增
w = torch.abs(self.hyper_w(state))
b = self.hyper_b(state)
q_tot = torch.bmm(agent_qs.unsqueeze(1), w.view(-1, self.num_agents, 1)).squeeze(1) + b
v = self.v(state)
return q_tot + v
两条路线的适用场景有明显差异。中心化评论家路线对协作与竞争混合的场景更友好,因为每个智能体可以有自己的奖励函数,天然支持非零和博弈;值分解路线则假设团队共享一个全局奖励,强调纯粹的协作任务,在星际争霸微操这类基准任务上表现非常出色。选择哪种路线,取决于你的任务是合作型还是混合动机型。
使用CTDE时需要注意的实践细节与局限
第一,全局信息的获取成本。CTDE要求训练阶段存在全局状态或至少所有智能体的观测拼接,如果部分可观测严重、智能体数量极多,中心化评论家的输入维度会爆炸。常见缓解手段包括注意力机制聚合邻居信息(如TarMAC、GraphMixer类方法),或者干脆用平均场近似来简化。
第二,训练与执行的分布偏移。训练时智能体看到的是联合策略下的数据,执行时却是各自独立行动,如果训练过程中没有充分探索其他智能体的策略空间,部署后遇到陌生行为组合,个体策略可能表现骤降。对此,MAPPO建议使用较大的批量和共享策略参数来增强稳定性,同时可以在训练中引入对手策略的多样性。
第三,可扩展性瓶颈。智能体数量从几个增加到几十个时,参数共享几乎成为必选项:所有智能体共用一个网络,用智能体ID的one-hot编码区分身份。这样既减少了参数量,也让经验在智能体之间可以复用。但代价是失去了对异构智能体(如不同型号机器人混编)的表达能力,异构场景需要考虑聚合网络或分组参数共享等改造。
最后要清醒地认识到,CTDE解决的主要是训练稳定性问题,而不是智能体之间的显式通信与协商问题。如果你的任务需要在执行阶段进行实时协调,或者存在需要学习通信协议的场景,还应该在CTDE框架上叠加通信学习机制(如CommNet、TarMAC)。把CTDE当作地基而不是全部,才能在复杂的多智能体系统设计中做出合理的技术选型。