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

PyTorch循环中原地操作触发RuntimeError报错求助

问题分析与解决

错误原因

触发RuntimeError: a view of a leaf Variable that requires grad is being used in an in-place operation.的核心原因是:

  • 你直接创建了带requires_grad=True的叶子节点张量result(通过torch.zeros((3, 3), requires_grad=True))
  • 后续的result[0] = input_tensor、result[i] = param * result[i-1]都是in-place内存修改操作,PyTorch禁止对需要梯度追踪的叶子节点执行此类操作——因为这会破坏计算图的梯度追踪链路,导致反向传播无法正常进行。

解决方案

方案1:通过拼接构建结果(推荐)

完全避免in-place操作,逐步计算每个时间步的结果,最后用torch.cat拼接成最终张量,所有操作都在计算图的正常追踪范围内:

import torch

def function(input_tensor, param):
    step_results = [input_tensor.unsqueeze(0)]  # 把初始张量转为(1,3)维度
    for i in range(1, 3):
        next_step = param * step_results[-1]
        step_results.append(next_step)
    return torch.cat(step_results, dim=0)  # 拼接成(3,3)的结果

input_tensor = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
param = torch.tensor(2.0, requires_grad=True)

output = function(input_tensor, param)
loss = output.sum()
loss.backward()

# 验证梯度是否正确计算
print(param.grad)       # 输出 tensor(18.)
print(input_tensor.grad)# 输出 tensor([3., 6., 9.])

方案2:修改张量创建方式,避免叶子节点的in-place操作

如果需要预先初始化张量,可以先创建不带梯度的张量,再通过克隆或赋值让它成为计算图的非叶子节点:

import torch

def function(input_tensor, param):
    result = torch.zeros((3, 3))  # 先创建无梯度的张量
    result = result.clone()       # 克隆后变为非叶子节点
    result[0] = input_tensor
    for i in range(1, 3):
        result[i] = param * result[i-1]
    result.requires_grad_(True)   # 开启梯度追踪
    return result

input_tensor = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
param = torch.tensor(2.0, requires_grad=True)

output = function(input_tensor, param)
loss = output.sum()
loss.backward()

方案1的逻辑更清晰,也更符合PyTorch构建计算图的最佳实践,能有效避免in-place操作带来的各种潜在问题。

内容的提问来源于stack exchange,提问作者Vinicius B. de S. Moreira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 07:32:41