---
title: 算子dtype类型不一致报错-昇腾社区
description: 在执行onnx2om进行模型导出时报错“op[xxx], The xxx op dtype is not same, type1:xxx, type2:xxx”。 onnx模型转换成om模型后，执行模型推理失败，报错提示为“Aicpu kernel execute failed”。
keywords: TopK算子;dtype类型
url: https://www.hiascend.com/document/caselibrary/detail/topic_0000001524596790
section: (其他)
---

# 算子dtype类型不一致报错-昇腾社区

URL: https://www.hiascend.com/document/caselibrary/detail/topic_0000001524596790
描述: 在执行onnx2om进行模型导出时报错“op[xxx], The xxx op dtype is not same, type1:xxx, type2:xxx”。 onnx模型转换成om模型后，执行模型推理失败，报错提示为“Aicpu kernel execute failed”。
关键词: TopK算子;dtype类型

昇腾文档 [了解详情](https://www.hiascend.com/document)

故障案例 [了解详情](https://www.hiascend.com/document/caselibrary)

算子dtype类型不一致报错

算子dtype类型不一致报错

2023/05/24

4.4k

问题信息

| 问题来源 | 产品大类 | 关键字 |
| --- | --- | ---|
| 官方 | 算子开发 | TopK算子、dtype类型 |

#### 问题现象描述

在执行onnx2om进行模型导出时报错“op[xxx], Thexxxop dtype is not same, type1:xxx, type2:xxx”。

onnx模型转换成om模型后，执行模型推理失败，报错提示为“Aicpu kernel execute failed”。

#### 原因分析

目前版本中TopK算子的数据类型仅支持int32，而TopK算子下层算子Initializer值一般为int64，这就导致下层算子在inftershape阶段后进行数据类型校验报错。

可以根据onnx图快速定位报错算子的上层输入为TopK算子，算子dtype类型不一致。

#### 解决措施

涉及动态shape的模型，可先将shape固定后再进行问题排查，防止报错后GE图中原始框架中的算子映射成PartitionedCall算子无法排查。初步分析分析如下：

1. 设置“export DUMP_GE_GRAPH=2”打开GE图，根据报错找到xxx-xxx-after_infershape.pbtxt图。
2. 在图中找到报错算子，结构一般为：[xxx] --> [topK] --> [报错算子]， 后对onnx进行修改。

```
import onnx
onnx_model = onnx.load('model.onnx')
graph = onnx_model.graph
for initializer in graph.initializer:
if initializer.name == 'xxx':    #找到init所在的node节点名,在onnx图中可以initializer.data_type = 6    #6是代表int32
onnx.save(onnx_model, 'model_fix.onnx')
```
3. 如还有下层算子的dtype类型不一致报错，可继续重复上述操作， 一般即可完成模型修改，不再影响om转换和离线推理。
4. 如影响层数较多，且远大于onnx整网一半以上的 graph.initializer，可先对整网initializer全部修改，然后恢复成不影响部分。

以某项目中PyTorch onnx2om为例进行具体说明。

1. 根据Device侧debug日志可知报错sub算子的输入dtype一个是int32， 一个是int64，如下图所示。

```
[ERROR] AICPU(15590,aicpu_scheduler): [sub.cc:63][AICPU][DoCompute:63][tid:15601]:Input[x1] data type[DT_INT32] and input[x2] data type[DT_INT64] must be same.
```
2. 由于内部动态shape的问题，om转换后生成的build图全是PartitionedCall节点，无法具体问题。

如果模型不走动态shape或者内部不存在动态shape，便可在om图中直接观察到算子的dtype类型不一致。
3. 使用 “export DUMP_GE_GRAPH=2 ”生成Dump图，在Dump图目录下找到ge_onnx_***_graph_0_after_infershape.pbtxt，可在GE图中在inftershape之后sub算子确实存在两个input，算子的dtype类型分别为int32和int64。
4. 返回到原ONNX图中查看，可以TopK算子的dtype类型为int32， 而向上排查需要将gather算子的init初始值修改为int32，与TopK算子保持一致。

```
import onnx
onnx_model = onnx.load('smoke.onnx')
graph = onnx_model.graph
for initializer in graph.initializer:
if initializer.name == '1113':    #找到init所在的node节点名
initializer.data_type = 6    #6是代表int32
onnx.save(onnx_model, 'dynamic_model_fix.onnx')
```
5. 修改完成后重新进行模型转换，依旧报错，利用onnxsim工具继续排查。

```
onnxsim smoke.onnx models.onnx
```
6. TopK算子输出不再插值cast，可以在模型转换的过程中看出有明显报错的div算子，继续进行问题分析。

问题出现在div算子中Initializer的初始值为int64，使得div算子输出（即sub算子的上一层的输入）为int64， 而TopK算子为int32。
7. 修改Div算子的Initializer初始值；使得Div算子的dtype类型为int32，TopK算子的dtype类型也为int32，在sub算子上的两个输入经过校验能为一致了。

```
import onnx
onnx_model = onnx.load('dynamic_model_fix_1212.onnx')
graph = onnx_model.graph
onnx_model.graph.output[0].type.tensor_type.shape.dim[0].dim_param = '?'     #修改输出dim0为动态
#参考issue[https://github.com/onnx/onnx/issues/654]
for initializer in graph.initializer:
if initializer.name == '1114':
initializer.data_type = 6
onnx.save(onnx_model, 'models_1212_fixed_div.onnx')
```
8. 重新进行模型转换后，推理成功。

本页内容

- 问题信息
- 问题现象描述
- 原因分析
- 解决措施
