NCNN 核心功能:模型格式、INT8 量化工具链与运行期选项
NCNN 核心功能:模型格式、INT8 量化工具链与运行期选项
NCNN 的能力边界由三件事决定:模型能不能转过来(转换工具与算子覆盖)、能不能跑得动(Vulkan 与线程、内存配置)、能不能够小够准(INT8 量化工具链)。
模型转换工具链
| 工具 | 输入 | 输出 | 说明 |
|---|---|---|---|
| pnnx | PyTorch 导出物 | param + bin | 官方推荐的 PyTorch 路径 |
| onnx2ncnn | ONNX 模型 | param + bin | 跨框架的通用入口 |
| ncnnoptimize | param + bin | 优化后的 param + bin | 合并常量、折叠算子、改 fp16 存储 |
| ncnn2table | param + bin + 校准图片列表 | 量化表 | 统计激活分布,支持 kl 等算法 |
| ncnn2int8 | param + bin + 量化表 | int8 模型 | 生成可被 opt.use_int8_inference 加载的模型 |
量化流程要点
NCNN 的量化是「先优化、再统计、后量化」三步,顺序不能颠倒:先把模型交给 ncnnoptimize 做结构优化,再用校准图片生成量化表,最后用 ncnn2int8 产出 int8 模型。
# 1. 结构优化,最后一个参数 65536 表示 fp16 存储,0 表示 fp32
./ncnnoptimize model.param model.bin model_opt.param model_opt.bin 65536
# 2. 生成量化表:mean / norm / shape / pixel 必须与推理代码的预处理一致
./ncnn2table model_opt.param model_opt.bin imagelist.txt model.table \
mean=[104.0,117.0,123.0] norm=[0.017,0.017,0.017] shape=[224,224,3] pixel=BGR thread=8 method=kl
# 3. 产出 int8 模型
./ncnn2int8 model_opt.param model_opt.bin model_int8.param model_int8.bin model.table
量化效果严重依赖校准集:imagelist.txt 每行一张图片路径,数量从几十到几百不等,覆盖度比数量更重要。mean、norm、shape、pixel 这四个参数是预处理参数,必须与推理代码里的预处理完全一致——它们与代码对不上,量化表统计出来的分布就是错的,精度会莫名下降却不报错,这是最常见的隐性坑。此外,不同层类型对 int8 的支持情况不同,部分层会保持浮点,具体以官方文档与 benchmark 结果为准。
运行期关键选项
| 选项 | 作用 | 实践建议 |
|---|---|---|
| opt.num_threads | CPU 线程数 | 按大核数量设置,避免占满导致界面卡顿 |
| opt.use_vulkan_compute | 启用 Vulkan 计算 | 有驱动才开,需配合 set_vulkan_device 指定设备 |
| opt.use_fp16_packed / use_fp16_storage / use_fp16_arithmetic | fp16 存储与计算 | 移动端 GPU 上收益明显,注意精度变化 |
| opt.use_int8_inference | 启用 int8 推理 | 加载 int8 模型时必须为 true |
| opt.use_packing_layout | 数据打包布局 | 默认开启,利于 SIMD 加速 |
| opt.lightmode | 用完即释放中间 blob | 移动端建议开启以压低内存峰值 |
| ncnn::set_cpu_powersave | CPU 功耗策略 | 按设备实测结果选择 |
| get_big_cpu_count() | 取大核数量 | 大小核架构上比总核数更适合用来设线程 |

