第 1 章:NCNN 简介
1. NCNN 简介
NCNN 是一个为移动端极致优化的高性能神经网络前向计算框架。无第三方依赖,跨平台,QQ、微信等多款产品中即使用 NCNN 进行模型推理。
Logo
为什么选择像素风格的 Logo,因为 NCNN 的作者和本文的作者一样,都是 Minecraft 的忠实粉丝!
NCNN 是市场上最早的、发展比较成熟的、为移动端优化的、支持广泛硬件的神经网络部署框架。NCNN 使用 BSD-3 开源协议。
NCNN 是纯 C++ 实现,不依赖与其他第三方计算库,极其轻量。此外兼容各种平台和生态,可以说是面向未来的部署框架,其中还包含了为 ARM NEON 架构的汇编级别的优化,可以说良心至极!
2. 研发团队
NCNN 项目属于腾讯的优图实验室,NCNN 的核心贡献者是腾讯优图实验室的 nihui。目前 NCNN 也是作为腾讯的主打神经网络部署框架面向广大开发者。
nihui 是可爱的男孩子哦!!!下面她的照片(来源:https://github.com/nihui):

伴随着 NCNN 的核心作者 nihui 提出 PNNX,NCNN 更加兼容 PyTorch 生态圈,为扩展 NCNN 部署生态,提供更好的移动端部署奠定坚实的基础。
3. NCNN 的生态
支持的平台:
- Linux
- Windows
- macOS
- Raspberry Pi
- Android
- NVIDIA Jetson
- iOS
- WebAssembly
- AllWinner D1
- Loongson 2K1000
- ......
支持的硬件:
- Intel-CPU
- Intel-GPU
- AMD-CPU
- AMD-GPU
- Nvidia
- Qcom-CPU
- Qcom-GPU
- ARM-CPU
- ARM-GPU
- Apple-CPU
- Apple-GPU
- ......
支持的模型:
- caffe
- pytorch
- mxnet
- onnx
- darknet
- keras
- tensorflow (MLIR)
- ......
官方极简示例代码:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "net.h"
int main() {
cv::Mat img = cv::imread("image.ppm", CV_LOAD_IMAGE_GRAYSCALE);
int w = img.cols;
int h = img.rows;
// subtract 128, norm to -1 ~ 1
ncnn::Mat in = ncnn::Mat::from_pixels_resize(img.data, ncnn::Mat::PIXEL_GRAY, w, h, 60, 60);
float mean[1] = { 128.f };
float norm[1] = { 1/128.f };
in.substract_mean_normalize(mean, norm);
ncnn::Net net;
net.load_param("model.param");
net.load_model("model.bin");
ncnn::Extractor ex = net.create_extractor();
ex.set_light_mode(true);
ex.set_num_threads(4);
ex.input("data", in);
ncnn::Mat feat;
ex.extract("output", feat);
return 0;
}
4. NCNN 的设计哲学
易用性
不仅让你能用,而且能学到东西。完全适合学习,完全可以用于创造自己的项目。包含很多简单的示例。
移植性
为什么使用 C++ 03?为了更好的移植性。最小前置知识原则。
Vulkan API?Vulkan 有更好的移植性,虽然有点难,也没有最快的。
可维护性
很容易看得懂,修改比较容易,优化代码都是可选的。
兼容性
高层 API 基本不变。
数据结构 Mat
Mat
只有三个维度 w
、h
、c
。为什么没有 batch
?因为不需要。
每一个 channel
都会进行数据对齐,在多线程上优化效果明显。
没有类型信息,让开发者自己设定。大多数情况下都是 float32
。约定大于配置。
模型文件格式
使用 .param
和 .bin
两种文件分别表示网络模型和权重。为什么要用文本表示网络模型?让开发者可以魔改网络结构。