You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch训练MADDPG时因原地操作引发梯度计算RuntimeError求解

问题描述

训练多智能体DDPG(MADDPG)演员-评论家网络,设置10000个episode,每个episode包含25个时间步。训练至第10个episode时,梯度计算环节触发以下错误:

RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [64, 100]], which is output 0 of AsStridedBackward0, is at version 3; expected version 2 instead. Hint: enable anomaly detection to find the operation that failed to compute its gradient, with torch.autograd.set_detect_anomaly(True).

用于梯度计算与模型更新的代码片段如下:

for agent_idx, agent in enumerate(self.agents):
    # torch.autograd.set_detect_anomaly(True)
    critic_value_ = agent.target_critic.forward(states_, new_actions).flatten()
    critic_value_[dones[:, 0]] = 0.0
    critic_value = agent.critic.forward(states, old_actions).flatten()

    target = rewards[:, agent_idx] + (agent.gamma * critic_value_)
    critic_loss = F.mse_loss(target, critic_value)
    agent.critic.optimizer.zero_grad()
    critic_loss.backward(retain_graph= True)
    agent.critic.optimizer.step()

    actor_loss = agent.critic.forward(states, mu).flatten()
    actor_loss = -torch.mean(actor_loss)
    agent.actor.optimizer.zero_grad()
    actor_loss.backward(retain_graph= True)
    agent.actor.optimizer.step()

    agent.update_network_parameters()

使用PyTorch版本为1.13.1+cu116,需解决该梯度计算错误。

解决方案
  • 修复核心inplace操作:错误的直接原因是critic_value_[dones[:, 0]] = 0.0这行代码对计算图中的张量进行了inplace修改,破坏了PyTorch自动梯度追踪的版本一致性。可以通过两种方式替换为非inplace操作:
    # 方式1:用torch.where创建新张量
    critic_value_ = agent.target_critic.forward(states_, new_actions).flatten()
    critic_value_ = torch.where(dones[:, 0].unsqueeze(-1), torch.zeros_like(critic_value_), critic_value_)
    # 方式2:先克隆原张量再修改
    critic_value_ = agent.target_critic.forward(states_, new_actions).flatten().clone()
    critic_value_[dones[:, 0]] = 0.0
    
  • 检查目标网络更新逻辑:确认agent.update_network_parameters()方法中没有对目标网络参数的inplace赋值操作。正确的软更新应该通过copy_方法实现,示例如下:
    # 目标网络软更新的标准实现(参考)
    def update_network_parameters(self):
        tau = self.tau
        # 更新目标评论家网络
        for target_param, local_param in zip(self.target_critic.parameters(), self.critic.parameters()):
            target_param.data.copy_(tau * local_param.data + (1.0 - tau) * target_param.data)
        # 更新目标演员网络
        for target_param, local_param in zip(self.target_actor.parameters(), self.actor.parameters()):
            target_param.data.copy_(tau * local_param.data + (1.0 - tau) * target_param.data)
    
  • 优化retain_graph的使用:当前代码中两次反向传播都设置了retain_graph=True,但仅第一次反向传播后需要保留计算图供第二次使用,第二次可以省略该参数(默认值为False),避免不必要的计算图占用和版本混乱:
    critic_loss.backward(retain_graph=True)
    agent.critic.optimizer.step()
    
    # ... 其他代码 ...
    
    actor_loss.backward()  # 无需再保留计算图
    agent.actor.optimizer.step()
    
  • 启用异常检测精准定位:取消代码中torch.autograd.set_detect_anomaly(True)的注释,重新运行训练,系统会输出触发版本不匹配的具体操作栈,帮助排查其他潜在的inplace操作问题。

内容的提问来源于stack exchange,提问作者Enigmacy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:33:20