1. 背景
前期我们利用torch框架实现了一个python版本的轨迹预测模型,经过近1个月的训练样本迭代,形成了一个性能基本稳定的模型版本。之后我们尝试将这个python模型转为onnx模型进行工程部署,遇到了很多问题,在此做个踩坑记录。
2. 问题
2.1 如何转为onnx模型
报错显示被覆盖
log显示有行数限制,转换报错后看不到具体报错内容;可直接导出全部log信息到本地进行查看
1
Python torch_to_onnx.py > error.log 2>&1
opset和torch版本
根据工程部门要求设置对应的 opset 和 torch 版本,修改 torch 版本可能涉及修改模型结构,会相对繁琐,opset 直接修改版本号后尝试运行即可;
c++算子修改
模型代码中涉及一部分结构使用c++编译实现,在进行ONNX转换的时候需要将这部分功能用Python重新实现,相关修改可能会降低程序运行效率;
argsort()算子用topk()替代
ONNX模型不支持argsort()操作,需要使用其它算子进行等效替换,这里推荐使用topk()进行替换;
layernorm算子不支持
首先需要明白layernorm的作用,layernorm是对每个样本的特征进行归一化,batchnorm是对每个batch的样本进行归一化;
layernorm算子不影响ONNX模型的导出,但是会影响后续模型的转换,需要去除网络中的layernorm层;这一步肯呢个降低模型指标,可以尝试在训练的时候添加layernorm但在转换onnx模型的时候去除layernorm;
2.2 转qualcomm平台的问题
nonzero算子不支持
加mask操作不支持,与tensor对应元素的检索方式有关,去除mask相关语句,如traj[traj_mask]
scatterND算子不支持
每个Tensor的索引不可缺省,检索的时候需要补全;维度索引缺省不支持;
Gather算子不支持
tensor类型不匹配,相应数据类型改为torch.float即可;
2.3 算力与内存
算力的定义
算力的概念可以理解为机器每秒进行多少次操作,一般使用单位TOPS(Tera Operations Per Second),1TOPS表示每秒进行10^12次计算;
FLOPS与OPS类似,OPS表示的是操作次数,而FLOPS是浮点操作次数;
单位换算:
- 1 PFLOPS = 1024 TFLOPS (T的数量级10^12)
- 1 TFLOPS = 1024 GFLOPS (G的数量级10^9)
- 1 GFLOPS = 1024 MFLOPS (M的数量级10^6)
onnx测算力的方法
测算力需要使用专门的onnx tools,因此要先完成Python模型到onnx模型的转换;
转换完成后,得到.onnx模型文件,然后执行以下代码:
1
2
3import onnx_tool
modelpath = "onnx_data/torch_v1_9_0_v1_3.onnx"
onnx_tool.model_profile(modelpath, savenode='node_table_v1_3.csv') # save profile table to txt file执行完成后得到.csv文件,文件内容为整个网络中每个算子的输入输出size和消耗的计算量;
onnx算力和内存的表示
csv文件中浮点计算量MACs指累加数量(1 MAC=2 FLOPs),内存计算单位是bytes,参数单位是元素个数;所以,得到MAC是算力后需要乘以2,换算为FLOPs的单位;
1
2
3
41 B(bytes) = 8 b(位)
1 KB = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB