ONNX (Open Neural Network Exchange) 是一种开放的神经网络模型表示格式,它使用单一文件存储整个模型,包括结构和权重。而NCNN则采用分离的文件结构。
理由包括:
- 分离关注点 - 结构和权重分开
- 效率和访问速度
- 移动设备优化
- 文件大小和内存管理
- 修改和调试方便
- 历史设计决策和NCNN自身的架构特点
为什么将 ONNX 模型转换为 NCNN 的两个文件格式
NCNN 将模型拆分为 .param 和 .bin 两个文件是一个经过精心设计的决策,特别是针对移动和嵌入式设备的优化。这种拆分有几个重要的技术原因:
1. 架构与权重分离的优势
ONNX 文件结构:单一文件包含网络结构和所有权重
方便分发和共享
但加载时需要解析整个文件
NCNN 双文件结构:
.param:轻量级文本文件,仅包含网络拓扑结构
.bin:二进制文件,专门存储权重数据
2. 性能优化原因
内存映射效率
cpp
// NCNN 可以直接内存映射 .bin 文件
memory_map = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
这允许系统仅将需要的权重数据页加载到物理内存,而不是一次性加载整个模型。
快速启动
markdown
网络启动时序:
1. 加载并解析小型 .param 文件 (~几十KB)
2. 按需延迟加载 .bin 中的权重
这使应用程序能够更快速地启动,特别是在资源受限的设备上。
3. 移动/嵌入式设备优化
NCNN 专为移动设备设计,其文件格式反映了这一点:
优化点 方式
内存占用 仅加载必要的权重
启动速度 快速解析小型结构文件
灵活性 结构修改无需重新编译权重数据
4. 开发与调试友好性
.param 文件可读性:
ini
7767517
75 83
Input data 0 1 data 0=224 1=224 2=3
Convolution conv1 1 1 data conv1 0=64 1=7 2=1 3=2 4=3 5=1 6=9408 9=1
…
这种人类可读的格式使开发人员可以:
直接检查和修改网络结构
诊断问题而无需专用工具
编写自动化脚本来分析或修改网络
5. 灵活的模型操作
NCNN 的双文件格式还支持:
go
// 结构修改示例
sed -i 's/stride=2/stride=1/g' model.ncnn.param
// 模型量化无需重复结构解析
./ncnnoptimize model.ncnn.param model.ncnn.bin model-int8.ncnn.param model-int8.ncnn.bin 2
6. 资源限制设备适应性
在如 Jetson 这样的设备上,.param 文件可以保存在更快的存储介质上,而较大的 .bin 文件可以放在较慢的存储上,从而优化资源使用。
通过这种结构与数据分离的设计,NCNN 提供了一种专为计算和内存受限环境优化的模型表示方式,使其特别适合于您正在使用的嵌入式设备。