使用 BM1688 SDK 的模型优化功能主要依赖其核心工具 BMCompiler(模型编译器),通过将主流框架模型(如 TensorFlow、PyTorch、Caffe 等)转换为 BM1688 芯片支持的BModel 格式,并在转换过程中完成编译、图优化、量化等优化操作。以下是具体步骤和关键操作说明:
一、环境准备
安装 SDK
首先确保已正确安装 BM1688 SDK(如 SOPHON SDK),包含bmcompiler工具链、模型转换脚本及依赖库(如bmnetc、bmnett等,对应不同框架)。
安装路径通常为/opt/sophon/sophon-sdk,工具可在/opt/sophon/sophon-sdk/x86_64/bin目录下找到。
准备输入模型
需提供训练好的原始模型文件(如 TensorFlow 的.pb、PyTorch 的.pth、Caffe 的.prototxt和.caffemodel等),并确认模型输入输出格式、数据类型(如 FP32)符合要求。
二、核心步骤:模型转换与优化(以静态编译为例)
1. 模型转换(生成 BModel)
BMCompiler 支持不同框架的模型转换,以下是常见框架的操作示例:
Caffe 模型
使用bmnetc工具转换,命令格式:
bmnetc --model=deploy.prototxt \
--weight=model.caffemodel \
--output=output_dir \
--target=BM1688 \
--opt=2 \ # 优化级别(0-2,2为最高)
--net_name=my_model \
--shapes=input:1,3,224,224 # 输入shape(静态编译需固定)
--opt=2:启用高级优化(如算子融合、冗余层移除)。
--shapes:静态编译需指定固定输入 shape,动态编译可设为最大 shape(如1,3,448,448)。
TensorFlow 模型
使用bmnett工具转换,命令格式:
bmnett --model=model.pb \
--input_names=input \
--output_names=output \
--target=BM1688 \
--opt=2 \
--shapes=input:1,224,224,3 \
--output=output_dir
PyTorch 模型
需先将.pth模型导出为 ONNX 格式,再用bmneto工具转换:
# 导出ONNX(PyTorch代码)
torch.onnx.export(model, dummy_input, "model.onnx", opset_version=11)
# 转换为BModel
bmneto --model=model.onnx \
--target=BM1688 \
--opt=2 \
--shapes=input:1,3,224,224 \
--output=output_dir
2. 量化优化(生成 INT8 模型)
为提升推理效率,BM1688 SDK 支持将 FP32 模型量化为 INT8 模型,步骤如下:
生成 Umodel
在模型转换时添加--gen_umodel参数,生成中间格式 Umodel(包含量化所需信息):
bmnetc --model=deploy.prototxt \
--weight=model.caffemodel \
--output=output_dir \
--target=BM1688 \
--gen_umodel # 生成Umodel
准备校准数据集
需提供少量代表性样本(如 100-500 张图片),用于计算量化参数(如权重、激活值的缩放因子)。
执行量化
使用bm_quantizer工具进行 INT8 量化:
bm_quantizer --model=output_dir/model.umodel \ # 输入Umodel
--calibration_data=calib_data.txt \ # 校准数据集路径列表
--output=quantized_umodel \
--quantize_method=kl # 量化算法(KL散度/Min-Max)
生成量化 BModel
将量化后的 Umodel 重新编译为 BModel:
bmnetc --umodel=quantized_umodel \
--output=quantized_bmodel \
--target=BM1688
图优化(自定义优化逻辑)
BMCompiler 支持通过自定义filter(过滤器)实现特定图优化(如移除冗余层、替换算子),步骤如下:
定义优化 Filter
在 C++ 中通过BM_FILTER宏定义 Filter,指定目标层类型、优化函数等:
// 示例:移除"Dropout"层
BM_FILTER(dropout_filter, "Dropout", BM_FILTER_PRIORITY_HIGH) {
auto* node = graph_node;
if (node->type() == "Dropout") {
graph->remove_node(node); // 移除节点
}
}
编译 Filter 插件
将 Filter 编译为动态链接库(.so),例如:
g++ -fPIC -shared -o custom_filter.so custom_filter.cpp -I$SDK/include
启用自定义 Filter
在模型转换时通过--plugin参数加载 Filter:
bmnetc --model=deploy.prototxt \
--weight=model.caffemodel \
--output=output_dir \
--plugin=./custom_filter.so # 加载自定义优化插件
三、验证优化效果
查看优化日志
转换过程中会输出日志,包含 “Graph Optimization” 步骤的详细信息(如融合了多少层、移除了多少节点)。
性能测试
使用 SDK 中的bmrt_test工具测试优化后 BModel 的推理速度:
bmrt_test --bmodel=output_dir/model.bmodel \
精度验证
通过对比优化前后模型的输出结果(如分类准确率、目标检测 mAP),确认优化未导致精度显著下降。
四、注意事项
静态编译的 BModel 性能优于动态编译,但仅支持固定输入 shape;动态编译适用于输入 shape 不固定的场景。
量化优化可能导致轻微精度损失,需通过校准数据集调整量化参数以平衡性能与精度。
复杂模型(如包含自定义算子)可能需要先通过bmop工具定义算子适配 BM1688 硬件,再进行优化。
通过以上步骤,可充分利用 BM1688 SDK 的模型优化功能,提升深度学习模型在 BM1688 芯片上的推理效率。具体细节可参考 SDK 自带的《BM1688 SOPHONSDK 开发指南》中的 “模型编译与优化” 章节。