bmrt_test工具使用及bmodel验证¶
bmrt_test工具¶
bmrt_test是基于bmruntime接口实现的对bmodel的正确性和实际运行性能的测试工具。包含以下功能:
直接用随机数据bmodel进行推理,验证bmodel的完整性及可运行性
通过固定输入数据直接用bmodel进行推理,会对输出与参考数据进行比对,验证证数据正确性
测试bmodel的实际运行时间
通过bmprofile机制进行bmodel的profile
bmrt_test参数说明¶
¶ args
type
Description
context_dir
string
模型编译出的结果文件夹,比对数据也是编译时生成的, 默认开启比对
不比对时,文件夹中包含compiation.bmodel一个文件即可
开启比对时,文件夹中要包含compiation.bmodel, input_ref_data.dat, output_ref_data.dat三个文件
bmodel
string
与context_dir二选一, 直接指定.bmodel文件,默认不开启比对
dev_id
int
可选, 在多芯平台上通过id指定运行设备, 默认是0
compare
bool
可选, 0表示不开比对, 1表示开启比对
accuracy_f
float
可选, 指定浮点数据比对误差门限,默认是0.01
accuracy_i
int
可选, 指定整数数据比对误差门限,默认是0
accuracy_i
int
可选, 指定整数数据比对误差门限,默认是0
shapes
string
可选, 指定测试时的输入shapes, 默认用bmodel的编译输入shape.
格式为”[x,x,x,x],[x,x]”, 对应于模型的输入顺序和个数
loopnum
int
可选, 指定连续运行次数,默认是1
thread_num
int
可选, 指定运行线程数目,默认是1,测试多线程正确性
net_idx
int
可选, 在包含多个网络的bmodel通过序号选择运行用的net
stage_idx
int
可选, 在包含多个stage的bmodel通过序号选择运行用的stage
subnet_time
bool
可选, 是否显示bmodel的subnet时间
bmrt_test输出¶
[BMRT][bmrt_test:981] INFO:net[vgg16_8_bmnetc] stage[0], launch total time is 19590 us (npu 19489 us, cpu 101 us) (1) [BMRT][bmrt_test:984] INFO:+++ The network[vgg16_8_bmnetc] stage[0] output_data +++ [BMRT][print_array:647] INFO:output data #0 shape: [4 32 120 68 ] < 3.49693 4.07723 4.30039 4.14311 4.11042 4.23445 4.23644 4.23897 4.23897 4.23897 4.23897 4.23897 4.23897 4.23897 4.23897 4.23897 ... > len=1044480 (2) [BMRT][print_array:647] INFO:output data #1 shape: [4 32 60 34 ] < 3.523 3.94491 4.09504 4.02145 3.95682 3.96846 3.96972 3.97314 3.9728 3.9728 3.9728 3.9728 3.9728 3.9728 3.9728 3.9728 ... > len=261120 [BMRT][print_array:647] INFO:output data #2 shape: [4 32 30 17 ] < 4.18294 5.16457 5.26347 5.16108 5.0436 4.99669 4.99279 4.99279 4.99279 4.99279 4.99279 4.99651 5.02305 5.0925 5.23303 5.24913 ... > len=65280 [BMRT][bmrt_test:1029] INFO:load input time(s): 0.008511 (3) [BMRT][bmrt_test:1030] INFO:calculate time(s): 0.019594 [BMRT][bmrt_test:1031] INFO:get output time(s): 0.006001 (4) [BMRT][bmrt_test:1032] INFO:compare time(s): 0.002886
- 主要关注点:
模型的纯推理时间,不包含加载输入和获取输出时间
推理数据展示,如开启比对,会显示比对成功等式信息
用s2d加载输入数据时间, 通常前处理会将数据直接放到设备上,没有这个时间消耗
用d2s取出输出数据时间, 通常表示在pcie上的数据传输时间,在soc上可以用mmap, 会更快
bmrt_test常用方法¶
bmrt_test --context_dir bmodel_dir # 运行bmodel,并比对数据,bmodel_dir中要包含compilation.bmodel/input_ref_data.dat/output_ref_data.dat bmrt_test --context_dir bmodel_dir --compare=0 # 运行bmodel,bmodel_dir中要包含compilation.bmodel bmrt_test --bmodel xxx.bmodel # 直接运行bmodel,不比对数据 bmrt_test --bmodel xxx.bmodel --stage_idx 0 --shapes "[1,3,224,224]" # 运行多stage的bmodel模型,指定运行stage0的bmodel # 以下命令是通过环境变量使用bmruntime提供的功能,其他应用程序也可以使用 BMRUNTIME_ENABLE_PROFILE=1 bmrt_test --bmodel xxx.bmodel # 生成profile数据:bmprofile_data-0 BMRT_SAVE_IO_TENSORS=1 bmrt_test --bmodel xxx.bmodel # 将模型推理的数据保存成input_ref_data.dat.bmrt和output_ref_data.dat.bmrt
比对数据生成与验证举例¶
模型编译完成后,进行比对运行
编译模型时要带上–cmp=True,默认是开启的,就会在编译输出文件夹中生成input_ref_data.dat和output_ref_data.dat文件
接着执行`bmrt_test –context_dir bmodel_dir`,便可验证模型推理数据正确性
pytorch原始模型和编译出的bmodel数据比对
将pytorch模型的输入input_data和输出output_data转为numpy的array(torch的tensor可以用tensor.numpy()),然后存文件(见以下代码)
# 单输入和单输出情况 input_data.astype(np.float32).tofile("input_ref_data.dat") # astype要根据bmodel的输入数据类型转换 output_data.astype(np.float32).tofile("output_ref_data.dat") # astype要根据bmodel的输出数据类型转换 # 多输入和多输出情况 with open("input_ref_data.dat", "wb") as f: for input_data in input_data_list: f.write(input_data.astype(np.float32).tobytes()) # astype要根据bmodel的输入数据类型转换 with open("output_ref_data.dat", "wb") as f: for output_data in output_data_list: f.write(output_data.astype(np.float32).tobytes()) # astype要根据bmodel的输出数据类型转换
把生成的input_ref_data.dat和output_ref_data.dat放到bmodel_dir文件夹下 然后`bmrt_test –context_dir bmodel_dir`, 看看结果是否出比对错误
bmodel推理数据用原模型验证
以pytorch模型为例
# 单输入单输出的情况 import torch import numpy as np pt_model_path = "xxx.pt" input_shape = (1,3,512,512) bmodel_dir = "compilation" model = torch.jit.load(pt_model_path) model.eval() # dtype要根据实际bmodel的输入类型转换 input_data = np.fromfile("{}/input_ref_data.dat".format(bmodel_dir), dtype=np.float32).reshape(1,3,512,512) print("input:", input_data) outputs = model(torch.tensor(input_data)) output = outputs[0] output = output.detach().numpy() output = output.flatten() # dtype要根据实际bmodel的输出类型转换 ref_output = np.fromfile("{}/output_ref_data.dat".format(bmodel_dir), dtype=np.float32); print("output:", output) abs_diff = np.abs(ref_output -output) print(np.sum(abs_diff)) print(np.mean(abs_diff)) print(np.max(abs_diff)) output.tofile("output_ref_data.dat.trace")
常见问题¶
编译模型时出现数据比对错误?
我们bmcompiler内部用的是0.01作为比对阈值,在少数情况下可能会超出范围而报错。
如果某一层实现的有问题,会出现成片比对错误,这时需要向我们开发人员反馈。
如果随机位置的零星错误,可能是个别值计算误差引起的。原因是编译时用的是随机数据,不排除会出现这种情况,所以建议编译时先加上 –cmp 0,在实际业务程序上验证结果是否正确
还有一种可能是网络中存在随机算子(如uniform_random)或者排序算子(如topk、nms、argmin等),由于在前面计算过程会产生输入数据的浮点尾数误差,即使很小也会导致排序结果的index不同。 这种情况下,可以看到比对出错的数据顺序上有差异,只能到实际业务上去测试