已关闭
[Bug-Report|缺陷反馈]: lstmbackward算子反向kernel报错 #1834
胡一航创建于  3月30日关闭于  4月1日
胡一航成员
3月30日 创建

Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.

Describe the current behavior / 问题描述 (Mandatory / 必填)

lstmbackward算子反向kernel报错
image.png

Environment / 环境信息 (Mandatory / 必填)

Atlas A3 训练系列产品/Atlas A3 推理系列产品 √
Atlas A2 训练系列产品/Atlas A2 推理系列产品 √

Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)

import copy
import pickle
import glob
import os
import torch
import torch_npu

from compare import benchmark_compare

from util_test import data_compare

torch_npu.npu.config.allow_internal_format = False

torch.npu.aclnn.allow_hf32 = False

def convert_tensor_to_device(tensor_obj, device: str = "cpu"):
"""
if is tensor sequence, convert to device, else return self
:param tensor_obj:
:param device:
:return:
"""
if isinstance(tensor_obj, torch.Tensor):
return tensor_obj.to(device)
if isinstance(tensor_obj, dict):
return {k: convert_tensor_to_device(v, device) for k, v in tensor_obj.items()}
if isinstance(tensor_obj, (tuple, list)):
return type(tensor_obj)([convert_tensor_to_device(v, device) for v in tensor_obj])
return tensor_obj

def convert_tensor_dtype_double(tensor_seq, is_high_precision: bool = False):
"""
During CPU calculation, the input of float16 or bfloat16 is converted into float32.
:return:
"""
if isinstance(tensor_seq, torch.Tensor):
if tensor_seq.dtype in [torch.float16, torch.bfloat16]:
return tensor_seq.to(torch.float32)
if tensor_seq.dtype == torch.float32:
return tensor_seq.to(torch.float64)
return tensor_seq
if isinstance(tensor_seq, dict):
return {k: convert_tensor_dtype_double(v) for k, v in tensor_seq.items()}
if isinstance(tensor_seq, (tuple, list)):
return type(tensor_seq)([convert_tensor_dtype_double(v) for v in tensor_seq])
return tensor_seq

def set_tensors_required_grad(inputs, grad_inputs):
if isinstance(inputs, torch.Tensor) and torch.is_floating_point(inputs):
inputs.requires_grad = True
grad_inputs.append(inputs)
return inputs
if isinstance(inputs, dict):
return {k: set_tensors_required_grad(v, grad_inputs) for k, v in inputs.items()}
if isinstance(inputs, (tuple, list)):
return type(inputs)([set_tensors_required_grad(v, grad_inputs) for v in inputs])
return inputs

def set_tensors_by_needs_input_grad(needs_input_grad, inputs, grad_inputs):
if isinstance(inputs, (tuple, list)):
input_data = [set_tensors_by_needs_input_grad(needs_input_grad[i], v, grad_inputs) for i, v in
enumerate(inputs)]
return type(inputs)(input_data)
if isinstance(inputs, dict):
return {k: set_tensors_by_needs_input_grad(needs_input_grad[k], v, grad_inputs) for k, v in inputs.items()}
if needs_input_grad is True:
inputs.requires_grad = True
grad_inputs.append(inputs)
return inputs
return inputs

def generate_grad_output(output_data):
if torch.is_tensor(output_data) and torch.is_floating_point(output_data):
return (torch.ones_like(output_data.detach()),)
if isinstance(output_data, (list, tuple)):
return (
torch.ones_like(i.detach())
for i in output_data
if torch.is_tensor(i) and torch.is_floating_point(i)
)
return tuple()

directory_path = "./"
files = glob.glob(os.path.join(directory_path, 'f8b3371f4042c934_2025.p'))

file_path = f"./outputs/input_data/torch.nn.BatchNorm2d/4cf57e1098259b38_33877933.p"

for file in files:
print("file",file)
with open(file, "rb") as f:
data = pickle.load(f)
torch.manual_seed(2025)
call_param_args = data.get("call_param_args")
call_param_kwargs = data.get("call_param_kwargs")
needs_input_grad = data.get("needs_input_grad")
grad_output = data.get("grad_output")
grad_output_npu = data.get("grad_output")
init_param_args = data.get("init_param_args")
init_param_kwargs = data.get("init_param_kwargs")
print("call_param_args",call_param_args[0].dtype)
grad_inputs = []
grad_inputs_npu = []
# call_param_args_new = list(call_param_args)
# call_param_args_new1 = call_param_args_new[0].to(torch.float32)
# call_param_args_new[0] = call_param_args_new1
init_cls_cpu = torch.nn.LSTM(*init_param_args, **init_param_kwargs).to(call_param_args[0].dtype)
# init_cls_npu = copy.deepcopy(init_cls_cpu)
call_param_args_npu = convert_tensor_to_device(tensor_obj=call_param_args, device="npu:0")
call_param_kwargs_npu = convert_tensor_to_device(tensor_obj=call_param_kwargs, device="npu:0")
# if call_param_args[0].dtype == torch.float16:
# call_param_args_db = convert_tensor_dtype_double(call_param_args, True)
# call_param_kwargs_db = convert_tensor_dtype_double(call_param_kwargs, True)
# else:
# call_param_args_db = call_param_args
# call_param_kwargs_db = call_param_kwargs
# print("call_param_args_db",call_param_args_db)
if grad_output:
# call_param_args_cpu = set_tensors_by_needs_input_grad(needs_input_grad["args"], call_param_args_db,
# grad_inputs)
# call_param_kwargs_cpu = set_tensors_by_needs_input_grad(needs_input_grad["kwargs"], call_param_kwargs_db,
# grad_inputs)
call_param_args_npu1 = set_tensors_by_needs_input_grad(needs_input_grad.get("args"), call_param_args_npu,
grad_inputs_npu)
call_param_kwargs_npu1 = set_tensors_by_needs_input_grad(needs_input_grad.get("kwargs"), call_param_kwargs_npu,
grad_inputs_npu)
else:
# call_param_args_cpu = set_tensors_required_grad(call_param_args_db, grad_inputs)
# call_param_kwargs_cpu = set_tensors_required_grad(call_param_kwargs_db, grad_inputs)
call_param_args_npu1 = set_tensors_required_grad(call_param_args_npu, grad_inputs_npu)
call_param_kwargs_npu1 = set_tensors_required_grad(call_param_kwargs_npu, grad_inputs_npu)

# output =init_cls_cpu(*call_param_args_cpu, **call_param_kwargs_cpu)

init_cls = init_cls_cpu.to("npu:0")
output_npu = init_cls(*call_param_args_npu1,**call_param_kwargs_npu1)
if not grad_output:
    # grad_output = generate_grad_output(output)
    grad_output_npu = generate_grad_output(output_npu)
else:
    grad_output_npu = convert_tensor_to_device(tensor_obj=grad_output_npu, device="npu:0")
# grads_cpu = torch.autograd.grad(output[0], grad_inputs, grad_output)
# print(grads_cpu)
with torch.autograd.profiler.profile(record_shapes=True) as prof:
    grads_npu = torch.autograd.grad(output_npu[0], grad_inputs_npu, grad_output_npu)
print(prof.key_averages(group_by_input_shape=True).table(sort_by="self_cpu_time_total"))
print("grads_npu",grads_npu)
# from single_compare import single_benchmark_compare
# ret = single_benchmark_compare(grads_npu.cpu(), grads_cpu,high_precision=True)  # high_precision参数控制高精度/高性能标准:True为高精度;False为高性能
# print("单标杆精度比对结果: ", ret.get_check_result())
# print(ret.get_result_msg())
# data_compare(grads_npu[0].cpu().detach().numpy(), grads_cpu[0].detach().numpy(), diff_thd=0.0010 ,pct_thd=0.0010)

Describe the expected behavior / 预期结果 (Mandatory / 必填)

不报错

image.png

Special notes for this issue/备注 (Optional / 选填)

likedislike
胡一航成员
3月30日 评论:

/assign

likedislike
CANN-robotCANN-robot成员
3月30日 将 huyihang1117 设为负责人
胡一航成员
3月30日 关联了pull request:修复lstmbackward算子kernel报错问题
胡一航成员
3月30日 关联了pull request:修复lstmbackward算子kernel报错问题
胡一航成员
3月30日 评论:

失败case已验证成功

likedislike
胡一航成员
4月1日 issue状态由 进行中 改变为 已完成
胡一航成员
4月1日 关闭了 issue