标杆数据生成工具
概述
在对 MindSpore Lite 模型进行基准测试前,开发者可以按照约定格式生成标杆数据(Benchmark Data)。基于生成的标杆数据运用benchmark工具进行基准测试,能够对原始模型和转换后的模型精度进行定量分析。
mslite_gold标杆数据生成工具,可基于原始模型输入数据input.npz
和推理得到的输出数据output.npz
生成标杆数据,本文介绍该工具的用法。
mslite_gold工具使用说明
开发者首先需要将原始模型输入数据和推理得到的输出数据,通过numpy
中的savez()
命令保存为.npz
格式的文件,再通过运行mslite_gold.py 分别将输入数据input.npz
和输出数据output.npz
转化为.bin
和.out
的二进制格式文件。
环境要求
python依赖库
numpy
>= 2.0.2onnx
>= 1.17.0onnxruntime
>= 1.19.2ast
>= 1.6.3collection
>= 0.1.6
使用示例
python mslite_gold.py --inputFile "/path/to/input.npz" --outputFile "/path/to/output.npz" --savePath "/path/to/save_data"
执行命令后,会在/path/to/save_data/
目录中生成如下文件:
input.bin
:输入数据,对每个输入Tensor的数据进行flatten
一维化,单独保存到一个二进制文件input.bin
,不含名称、dtype、shape等元信息。output.out
:输出数据,所有输出内容保存到一个文本文件,格式如下:
每个输出Tensor占用2行:
name dim shape1 [shape2 ...]
data0 data1 ...
第一行:记录输出Tensor的元信息,依次为:名称、维度、形状
第二行:记录输出Tensor的数据。
示例:
out_0 2 2 3
1.0 2.0 3.0 4.0 5.0 6.0
表示一个名称为out_0
,维度是2维,形状是[2, 3],内容是[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]
的Tensor。
下面以ONNX模型生成标杆数据为例,详细介绍工具的用法。
随机生成输入,进行模型推理,再将输入输出保存为
.npz
格式。onnx_demo.py示例代码 支持基于ONNX模型随机生成数据,或手动输入数据,并执行推理获得输出数据。手动输入数据时,可以通过参数
--inDataFile
来确定输入数据路径。如果模型是动态shape类型,需通过参数--inputShape
来确定输入尺寸。参数--inDataFile
和--inputShape
非必须,用户可以根据自身的使用场景来自由选用。下面是示例代码的基础使用示例:python onnx_demo.py --modelFile "/path/to/model_example.onnx" --savePath "/path/to/data_example"
/path/to/data_example/
目录中会生成input.npz
和output.npz
文件。将输入输出的
npz
文件转化成标杆数据文件。python mslite_gold.py --inputFile "/path/to/data_example/input.npz" --outputFile "/path/to/data_example/output.npz" --savePath "/path/to/save_data"
最后,在
/path/to/save_data
目录中会生成上述的标杆数据文件。
mslite_gold工具代码细节
以下展示标杆数据生成的代码细节,先转换input,再转换output。
import os
import numpy as np
from collections import OrderedDict
def save_bin(args):
try:
input_dict = np.load(args.inputFile)
print(f"Loaded inputs from {args.inputFile}: {list(input_dict.keys())}")
except Exception as e:
print(f"Error loading inputs: {e}")
return
i = 0
input_dict=OrderedDict(input_dict)
for key , input_data in input_dict.items():
print(f"input {key}: shape={input_data.shape}, dtype={input_data.dtype}")
if np.issubdtype(input_data.dtype, np.integer):
input_data.astype(np.int32).flatten().tofile(os.path.join(args.savePath, f"input.bin{i}"))
else:
input_data.flatten().tofile(os.path.join(args.savePath, f"input.bin{i}"))
i = i + 1
try:
output_dict = np.load(args.outputFile)
print(f"Loaded outputs from {args.outputFile}: {list(output_dict.keys())}")
except Exception as e:
print(f"Error loading outputs: {e}")
return
opened = 0
output_dict = OrderedDict(output_dict)
output_file = os.path.join(args.savePath, 'model.out')
for i , output_data in output_dict.items():
print(f"output {i}: shape={output_data.shape}, dtype={output_data.dtype}")
mode = 'w' if opened == 0 else 'a'
if str(output_data.shape) == "[]":
output_shape = [1]
else:
output_shape = output_data.shape
with open(output_file, mode) as text_file:
opened = 1
if len(output_shape) == 0:
output_shape.append(len(output_data))
text_file.write(f"{i} {len(output_data.shape)} ")
text_file.write(" ".join([str(s) for s in output_data.shape]))
text_file.write('\n')
print(f"result shape: {len(output_data.flatten())}")
for k in output_data.flatten():
text_file.write(f"{k} ")
text_file.write('\n')