使用 ncnn 将 pytorch 模型部署到安卓手机
- 在编译 NCNN 时开启图形卡支持。Vulkan 用于 GPU,设置
-DNCNN_VULKAN=ON。 - MobileNetV3
在编译到 MT 时开启 CMAKE 0091 特性
cmake_minimum_required(VERSION 3.20.0)
cmake_policy(SET CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
project("client-project")
训练 YOLO
\Envs\torch\Scripts\activate.ps1
python train.py --batch 6 --workers 2 --imgsz 960 --epochs 300 --data "\Core\yaml\data.yaml" --cfg "\Core\yaml\cfg.yaml" --weights \ Core\weights\best.pt --device 0
模型转换
from torch import nn
import torch.utils.model_zoo as model_zoo
import torch.onnx
from libs import define
from libs.net import Net
from libs.dataset import ImageDataset
import os
test_data = ImageDataset(define.testPath,False)
test_loader = torch.utils.data.DataLoader( test_data, batch_size=1, shuffle=True)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = Net(out_dim=19).to(device)
model.load_state_dict(torch.load( "./widget/last.pt" ))
model.eval()
def saveOnnx():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
label = target.long()
y = model(data)
# 导出模型
torch.onnx.export(model, # 正在运行的模型
data, # 模型输入(或多个输入的元组)
"./widget/best.onnx", # 保存模型的位置(可以是文件或文件对象)
export_params=True, # 将训练好的参数权重存储在模型文件中
opset_version=10, # 导出模型的 ONNX 版本
do_constant_folding=True, # 是否执行常量折叠以进行优化
input_names = ['input'], # 模型的输入名称
output_names = ['output'], # 模型的输出名称
dynamic_axes={'input': {0:'batch_size'}, # 可变长度轴
'output': {0:'batch_size'}})
traced_script_module = torch.jit.trace(model, data)
return
saveOnnx()
# 转换
os.system("python -m onnxsim ./widget/best.onnx ./widgetbest-sim.onnx")
os.system("./bin/onnx2ncnn.exe ./widget/best-sim.onnx ./widget/best.param ./widget/best.bin")
os.system("./bin/ncnnoptimize.exe ./widget/best.param ./widget/best.bin ./widget/best-opt.param ./widget/best-opt.bin 65536")
python .\export.py --weights weights/best.pt --img 960 --batch 1 --train
python -m onnxsim best.onnx best-sim.onnx
.\onnx2ncnn.exe best-sim.onnx best.param best.bin
ncnnoptimize best.param best.bin best-opt.param best-opt.bin 65536
Git 克隆 ncnn 仓库及子模块
$ git clone https://github.com/Tencent/ncnn.git
$ cd ncnn
$ git submodule update --init
- 为 Linux 构建
- 使用 VS2017 为 Windows x64 构建
- 为 macOS 构建
- 使用交叉编译为 ARM Cortex-A 系列构建
- 使用交叉编译为 Hisilicon 平台构建
- 为 Android 构建
- 在 macOS 上使用 xcode 为 iOS 构建
- 为 WebAssembly 构建
- 为 AllWinner D1 构建
- 为 Loongson 2K1000 构建
- 为 Android 上的 Termux 构建
为 Linux 构建
安装所需的构建依赖项:
- git
- g++
- cmake
- protocol buffer (protobuf) 头文件和 protobuf 编译器
- vulkan 头文件和加载器库
- glslang
- (可选) opencv # 用于构建示例
一般来说,如果你拥有过去 10 年的 Intel、AMD 或 Nvidia GPU,Vulkan 就可以轻松使用。
在某些系统上,目前(2020 年 10 月)可能没有易于获得的 Vulkan 驱动,因此你可能需要禁用 Vulkan 的使用。这适用于 Raspberry Pi 3(但正在开发中有一个实验性的开源 Vulkan 驱动,尚未准备好)。Nvidia Tegra 系列设备(如 Nvidia Jetson)应该支持 Vulkan。确保安装了最新的软件以获得最佳体验。
在 Debian、Ubuntu 或 Raspberry Pi OS 上,你可以使用以下命令安装所有必需的依赖项:
sudo apt install build-essential git cmake libprotobuf-dev protobuf-compiler libvulkan-dev vulkan-utils libopencv-dev
要使用 Vulkan 后端,你需要安装 Vulkan 头文件、一个 Vulkan 驱动加载器、GLSL 到 SPIR-V 编译器和 vulkaninfo 工具。最好从你的发行版仓库中获取。或者,从 https://vulkan.lunarg.com/sdk/home 下载并安装完整的 Vulkan SDK(大小约为 200MB;它包含所有头文件、文档和预构建加载器,以及一些额外的工具和所有内容的源代码)。
wget https://sdk.lunarg.com/sdk/download/1.2.189.0/linux/vulkansdk-linux-x86_64-1.2.189.0.tar.gz?Human=true -O vulkansdk-linux-x86_64-1.2.189.0.tar.gz
tar -xf vulkansdk-linux-x86_64-1.2.189.0.tar.gz
export VULKAN_SDK=$(pwd)/1.2.189.0/x86_64
在稍后构建 ncnn 时使用 Vulkan,你还需要为你的 GPU 拥有 Vulkan 驱动。对于 AMD 和 Intel GPU,这些可以在 Mesa 图形驱动中找到,通常在所有发行版中默认安装(例如,在 Debian/Ubuntu 上使用 sudo apt install mesa-vulkan-drivers)。对于 Nvidia GPU,必须下载并安装专有 Nvidia 驱动(某些发行版会以更简单的方式允许安装)。安装 Vulkan 驱动后,使用 vulkaninfo 或 vulkaninfo | grep deviceType 确认 Vulkan 库和驱动是否正常工作,它应该列出 GPU 设备类型。如果安装了多个 GPU(包括集成 GPU 和独立 GPU 的情况,常见于笔记本电脑),你可能需要记下设备的顺序以便稍后使用。
Nvidia Jetson 设备中的 Vulkan 支持应包含在 Nvidia 提供的 SDK (Jetpack) 或预构建的操作系统镜像中。
Raspberry Pi 的 Vulkan 驱动是存在的,但尚未成熟。你可以根据自己的判断进行实验,并报告结果和性能。
cd ncnn
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DNCNN_VULKAN=ON -DNCNN_SYSTEM_GLSLANG=ON -DNCNN_BUILD_EXAMPLES=ON ..
make -j$(nproc)
你可以向上面的 cmake 添加 -GNinja 来使用 Ninja 构建系统(使用 ninja 或 cmake --build . 调用构建)。
对于 Nvidia Jetson 设备,向 cmake 添加 -DCMAKE_TOOLCHAIN_FILE=../toolchains/jetson.toolchain.cmake。
对于 Rasberry Pi 3,向 cmake 添加 -DCMAKE_TOOLCHAIN_FILE=../toolchains/pi3.toolchain.cmake -DPI3=ON。你也可以考虑禁用 Vulkan 支持,因为 Raspberry Pi 的 Vulkan 驱动仍不成熟,但启用支持并未使用它也不会有坏处。
通过运行一些示例来验证构建:
cd ../examples
../build/examples/squeezenet ../images/256-ncnn.png
[0 AMD RADV FIJI (LLVM 10.0.1)] queueC=1[4] queueG=0[1] queueT=0[1]
[0 AMD RADV FIJI (LLVM 10.0.1)] bugsbn1=0 buglbia=0 bugcopc=0 bugihfa=0
[0 AMD RADV FIJI (LLVM 10.0.1)] fp16p=1 fp16s=1 fp16a=0 int8s=1 int8a=1
532 = 0.163452
920 = 0.093140
716 = 0.061584
你也可以运行基准测试(第 4 个参数是使用的 GPU 设备索引,参考 vulkaninfo,如果你有多个 GPU):
cd ../benchmark
../build/benchmark/benchncnn 10 $(nproc) 0 0
[0 AMD RADV FIJI (LLVM 10.0.1)] queueC=1[4] queueG=0[1] queueT=0[1]
[0 AMD RADV FIJI (LLVM 10.0.1)] bugsbn1=0 buglbia=0 bugcopc=0 bugihfa=0
[0 AMD RADV FIJI (LLVM 10.0.1)] fp16p=1 fp16s=1 fp16a=0 int8s=1 int8a=1
num_threads = 4
powersave = 0
gpu_device = 0
cooling_down = 1
squeezenet min = 4.68 max = 4.99 avg = 4.85
squeezenet_int8 min = 38.52 max = 66.90 avg = 48.52
要在 CPU 上运行基准测试,将第 5 个参数设置为 -1。
使用 Visual Studio Community 2017 为 Windows x64 构建
从 https://visualstudio.microsoft.com/vs/community/ 下载并安装 Visual Studio Community 2017。
启动命令提示符:Start → Programs → Visual Studio 2017 → Visual Studio Tools → x64 Native Tools Command Prompt for VS 2017
从 https://github.com/google/protobuf/archive/v3.4.0.zip 下载 protobuf-3.4.0。
构建 protobuf 库:
cd <protobuf-root-dir>
mkdir build
cd build
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_MSVC_STATIC_RUNTIME=OFF ../cmake
nmake
nmake install
(可选) 从 https://vulkan.lunarg.com/sdk/home 下载并安装 Vulkan SDK。
构建 ncnn 库(将 protobuf-root-dir 替换为正确的路径):
cd <ncnn-root-dir>
mkdir -p build
cd build
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%cd%/install -DProtobuf_INCLUDE_DIR=<protobuf-root-dir>/build/install/include -DProtobuf_LIBRARIES=<protobuf-root-dir>/build/install/lib/libprotobuf.lib -DProtobuf_PROTOC_EXECUTABLE=<protobuf-root-dir>/build/install/bin/protoc.exe -DNCNN_VULKAN=ON ..
nmake
nmake install
注意:为了加快多核机器上的编译过程,推荐使用 -G 标志配置 cmake 来使用 jom 或 ninja。
为 macOS 构建
首先根据你的需求安装 Xcode 或 Xcode 命令行工具。
然后通过 homebrew 安装 protobuf 和 libomp。
brew install protobuf libomp
从 https://vulkan.lunarg.com/sdk/home 下载并安装 Vulkan SDK。
wget https://sdk.lunarg.com/sdk/download/1.2.189.0/mac/vulkansdk-macos-1.2.189.0.dmg?Human=true -O vulkansdk-macos-1.2.189.0.dmg
hdiutil attach vulkansdk-macos-1.2.189.0.dmg
sudo /Volumes/vulkansdk-macos-1.2.189.0/InstallVulkan.app/Contents/MacOS/InstallVulkan --root `pwd`/vulkansdk-macos-1.2.189.0 --accept-licenses --default-answer --confirm-command install
hdiutil detach /Volumes/vulkansdk-macos-1.2.189.0
# 设置环境变量
export VULKAN_SDK=`pwd`/vulkansdk-macos-1.2.189.0/macOS
cd <ncnn-root-dir>
mkdir -p build
cd build
cmake -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" \
-DVulkan_INCLUDE_DIR=`pwd`/../vulkansdk-macos-1.2.189.0/MoltenVK/include \
-DVulkan_LIBRARY=`pwd`/../vulkansdk-macos-1.2.189.0/MoltenVK/dylib/macOS/libMoltenVK.dylib \
-DNCNN_VULKAN=ON -DNCNN_BUILD_EXAMPLES=ON ..
cmake --build . -j 4
cmake --build . --target install
注意:如果在安装过程中遇到与 libomp 相关的错误,你也可以查看我们的 GitHub Actions 此处 来安装和使用 openmp。
使用交叉编译为 ARM Cortex-A 系列构建
从 https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads 下载 ARM 工具链。
export PATH="<your-toolchain-compiler-path>:${PATH}"
或者安装发行版提供的交叉编译器(例如,在 Debian / Ubuntu 上,你可以执行 sudo apt install g++-arm-linux-gnueabi g++-arm-linux-gnueabihf g++-aarch64-linux-gnu)。
根据你的需求,构建以下一个或多个目标。
AArch32 软浮点目标 (arm-linux-gnueabi)
cd <ncnn-root-dir>
mkdir -p build-arm-linux-gnueabi
cd build-arm-linux-gnueabi
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-linux-gnueabi.toolchain.cmake ..
make -j$(nproc)
AArch32 硬浮点目标 (arm-linux-gnueabihf)
cd <ncnn-root-dir>
mkdir -p build-arm-linux-gnueabihf
cd build-arm-linux-gnueabihf
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-linux-gnueabihf.toolchain.cmake ..
make -j$(nproc)
AArch64 GNU/Linux 目标 (aarch64-linux-gnu)
cd <ncnn-root-dir>
mkdir -p build-aarch64-linux-gnu
cd build-aarch64-linux-gnu
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/aarch64-linux-gnu.toolchain.cmake ..
make -j$(nproc)
使用交叉编译为 Hisilicon 平台构建
下载并安装 Hisilicon SDK。工具链应位于 /opt/hisi-linux/x86-arm。
cd <ncnn-root-dir>
mkdir -p build
cd build
# 选择一个 cmake 工具链文件,取决于你的目标平台
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/hisiv300.toolchain.cmake ..
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/hisiv500.toolchain.cmake ..
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/himix100.toolchain.cmake ..
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/himix200.toolchain.cmake ..
make -j$(nproc)
make install
为 Android 构建
你可以使用来自 https://github.com/Tencent/ncnn/releases 的预构建 ncnn-android-lib.zip。
从 http://developer.android.com/ndk/downloads/index.html 下载 Android NDK 并安装它,例如:
unzip android-ndk-r21d-linux-x86_64.zip
export ANDROID_NDK=<your-ndk-root-path>
(可选) 移除 Android NDK 中的硬编码调试标志 android-ndk issue。
# 打开 $ANDROID_NDK/build/cmake/android.toolchain.cmake
# 删除 "-g" 行
list(APPEND ANDROID_COMPILER_FLAGS
-g
-DANDROID
构建 armv7 库
cd <ncnn-root-dir>
mkdir -p build-android-armv7
cd build-android-armv7
cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \
-DANDROID_PLATFORM=android-14 ..
# 如果你想启用 Vulkan,则需要平台 API 版本 >= android-24
cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI="armeabi-v7a" -DANDROID_ARM_NEON=ON \
-DANDROID_PLATFORM=android-24 -DNCNN_VULKAN=ON ..
make -j$(nproc)
make install
选择 build-android-armv7/install 文件夹用于进一步的 JNI 使用。
构建 aarch64 库:
cd <ncnn-root-dir>
mkdir -p build-android-aarch64
cd build-android-aarch64
cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake"\
-DANDROID_ABI="arm64-v8a" \
-DANDROID_PLATFORM=android-21 ..
# 如果你想启用 Vulkan,则需要平台 API 版本 >= android-24
cmake -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \
-DANDROID_ABI="arm64-v8a" \
-DANDROID_PLATFORM=android-24 -DNCNN_VULKAN=ON ..
make -j$(nproc)
make install
选择 build-android-aarch64/install 文件夹用于进一步的 JNI 使用。
在 macOS 上使用 xcode 为 iOS 构建
你可以使用来自 https://github.com/Tencent/ncnn/releases 的预构建 ncnn.framework、glslang.framework 和 openmp.framework。
安装 xcode
如果你想构建启用 bitcode 的库,可以将以下 cmake 参数中的 -DENABLE_BITCODE=0 替换为 -DENABLE_BITCODE=1。
下载并安装 openmp 以启用 iPhoneOS 上的多线程推理功能
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/openmp-11.0.0.src.tar.xz
tar -xf openmp-11.0.0.src.tar.xz
cd openmp-11.0.0.src
# 应用一些编译修复
sed -i'' -e '/.size **kmp_unnamed_critical_addr/d' runtime/src/z_Linux_asm.S
sed -i'' -e 's/**kmp_unnamed_critical_addr/\_\_\_kmp_unnamed_critical_addr/g' runtime/src/z_Linux_asm.S
mkdir -p build-ios
cd build-ios
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/ios.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install \
-DIOS_PLATFORM=OS -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 -DIOS_ARCH="armv7;arm64;arm64e" \
-DPERL_EXECUTABLE=/usr/local/bin/perl \
-DLIBOMP_ENABLE_SHARED=OFF -DLIBOMP_OMPT_SUPPORT=OFF -DLIBOMP_USE_HWLOC=OFF ..
cmake --build . -j 4
cmake --build . --target install
# 将 openmp 库和头文件复制到 xcode 工具链 sysroot
sudo cp install/include/\* /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include
sudo cp install/lib/libomp.a /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib
下载并安装 openmp 以启用 iPhoneSimulator 上的多线程推理功能
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/openmp-11.0.0.src.tar.xz
tar -xf openmp-11.0.0.src.tar.xz
cd openmp-11.0.0.src
# 应用一些编译修复
sed -i'' -e '/.size **kmp_unnamed_critical_addr/d' runtime/src/z_Linux_asm.S
sed -i'' -e 's/**kmp_unnamed_critical_addr/\_\_\_kmp_unnamed_critical_addr/g' runtime/src/z_Linux_asm.S
mkdir -p build-ios-sim
cd build-ios-sim
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/ios.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install \
-DIOS_PLATFORM=SIMULATOR -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 -DIOS_ARCH="i386;x86_64" \
-DPERL_EXECUTABLE=/usr/local/bin/perl \
-DLIBOMP_ENABLE_SHARED=OFF -DLIBOMP_OMPT_SUPPORT=OFF -DLIBOMP_USE_HWLOC=OFF ..
cmake --build . -j 4
cmake --build . --target install
# 将 openmp 库和头文件复制到 xcode 工具链 sysroot
sudo cp install/include/\* /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/include
sudo cp install/lib/libomp.a /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib
打包 openmp 框架:
cd <openmp-root-dir>
mkdir -p openmp.framework/Versions/A/Headers
mkdir -p openmp.framework/Versions/A/Resources
ln -s A openmp.framework/Versions/Current
ln -s Versions/Current/Headers openmp.framework/Headers
ln -s Versions/Current/Resources openmp.framework/Resources
ln -s Versions/Current/openmp openmp.framework/openmp
lipo -create build-ios/install/lib/libomp.a build-ios-sim/install/lib/libomp.a -o openmp.framework/Versions/A/openmp
cp -r build-ios/install/include/\* openmp.framework/Versions/A/Headers/
sed -e 's/**NAME**/openmp/g' -e 's/**IDENTIFIER**/org.llvm.openmp/g' -e 's/**VERSION**/11.0/g' Info.plist > openmp.framework/Versions/A/Resources/Info.plist
下载并安装 Vulkan SDK。
wget https://sdk.lunarg.com/sdk/download/1.2.189.0/mac/vulkansdk-macos-1.2.189.0.dmg?Human=true -O vulkansdk-macos-1.2.189.0.dmg
hdiutil attach vulkansdk-macos-1.2.189.0.dmg
sudo /Volumes/vulkansdk-macos-1.2.189.0/InstallVulkan.app/Contents/MacOS/InstallVulkan --root `pwd`/vulkansdk-macos-1.2.189.0 --accept-licenses --default-answer --confirm-command install
hdiutil detach /Volumes/vulkansdk-macos-1.2.189.0
# 设置环境变量
export VULKAN_SDK=`pwd`/vulkansdk-macos-1.2.189.0/macOS
为 iPhoneOS 构建库:
cd <ncnn-root-dir>
mkdir -p build-ios
cd build-ios
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/ios.toolchain.cmake -DIOS_PLATFORM=OS -DIOS_ARCH="armv7;arm64;arm64e" \
-DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 \
-DOpenMP_C_FLAGS="-Xclang -fopenmp" -DOpenMP_CXX_FLAGS="-Xclang -fopenmp" \
-DOpenMP_C_LIB_NAMES="libomp" -DOpenMP_CXX_LIB_NAMES="libomp" \
-DOpenMP_libomp_LIBRARY="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libomp.a" \
-DNCNN_BUILD_BENCHMARK=OFF ..
# Vulkan 仅在 arm64 设备上可用
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/ios.toolchain.cmake -DIOS_PLATFORM=OS64 -DIOS_ARCH="arm64;arm64e" \
-DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 \
-DOpenMP_C_FLAGS="-Xclang -fopenmp" -DOpenMP_CXX_FLAGS="-Xclang -fopenmp" \
-DOpenMP_C_LIB_NAMES="libomp" -DOpenMP_CXX_LIB_NAMES="libomp" \
-DOpenMP_libomp_LIBRARY="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/libomp.a" \
-DVulkan_INCLUDE_DIR=`pwd`/../vulkansdk-macos-1.2.189.0/MoltenVK/include \
-DVulkan_LIBRARY=`pwd`/../vulkansdk-macos-1.2.189.0/MoltenVK/dylib/iOS/libMoltenVK.dylib \
-DNCNN_VULKAN=ON -DNCNN_BUILD_BENCHMARK=OFF ..
cmake --build . -j 4
cmake --build . --target install
为 iPhoneSimulator 构建库:
cd <ncnn-root-dir>
mkdir -p build-ios-sim
cd build-ios-sim
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/ios.toolchain.cmake -DIOS_PLATFORM=SIMULATOR -DIOS_ARCH="i386;x86_64" \
-DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=0 \
-DOpenMP_C_FLAGS="-Xclang -fopenmp" -DOpenMP_CXX_FLAGS="-Xclang -fopenmp" \
-DOpenMP_C_LIB_NAMES="libomp" -DOpenMP_CXX_LIB_NAMES="libomp" \
-DOpenMP_libomp_LIBRARY="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/libomp.a" \
-DNCNN_BUILD_BENCHMARK=OFF ..
cmake --build . -j 4
cmake --build . --target install
打包 glslang 框架:
cd <ncnn-root-dir>
mkdir -p glslang.framework/Versions/A/Headers
mkdir -p glslang.framework/Versions/A/Resources
ln -s A glslang.framework/Versions/Current
ln -s Versions/Current/Headers glslang.framework/Headers
ln -s Versions/Current/Resources glslang.framework/Resources
ln -s Versions/Current/glslang glslang.framework/glslang
libtool -static build-ios/install/lib/libglslang.a build-ios/install/lib/libSPIRV.a build-ios/install/lib/libOGLCompiler.a build-ios/install/lib/libOSDependent.a -o build-ios/install/lib/libglslang_combined.a
libtool -static build-ios-sim/install/lib/libglslang.a build-ios-sim/install/lib/libSPIRV.a build-ios-sim/install/lib/libOGLCompiler.a build-ios-sim/install/lib/libOSDependent.a -o build-ios-sim/install/lib/libglslang_combined.a
lipo -create build-ios/install/lib/libglslang_combined.a build-ios-sim/install/lib/libglslang_combined.a -o glslang.framework/Versions/A/glslang
cp -r build/install/include/glslang glslang.framework/Versions/A/Headers/
sed -e 's/**NAME**/glslang/g' -e 's/**IDENTIFIER**/org.khronos.glslang/g' -e 's/**VERSION**/1.0/g' Info.plist > glslang.framework/Versions/A/Resources/Info.plist
打包 ncnn 框架:
cd <ncnn-root-dir>
mkdir -p ncnn.framework/Versions/A/Headers
mkdir -p ncnn.framework/Versions/A/Resources
ln -s A ncnn.framework/Versions/Current
ln -s Versions/Current/Headers ncnn.framework/Headers
ln -s Versions/Current/Resources ncnn.framework/Resources
ln -s Versions/Current/ncnn ncnn.framework/ncnn
lipo -create build-ios/install/lib/libncnn.a build-ios-sim/install/lib/libncnn.a -o ncnn.framework/Versions/A/ncnn
cp -r build-ios/install/include/\* ncnn.framework/Versions/A/Headers/
sed -e 's/**NAME**/ncnn/g' -e 's/**IDENTIFIER**/com.tencent.ncnn/g' -e 's/**VERSION**/1.0/g' Info.plist > ncnn.framework/Versions/A/Resources/Info.plist
选择 ncnn.framework、glslang.framework 和 openmp.framework 文件夹进行应用开发。
为 WebAssembly 构建
安装 Emscripten
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install 2.0.8
./emsdk activate 2.0.8
source emsdk/emsdk_env.sh
不带任何扩展名构建以实现通用兼容性:
mkdir -p build
cd build
cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
-DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF -DNCNN_AVX=OFF \
-DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF ..
cmake --build . -j 4
cmake --build . --target install
带 WASM SIMD 扩展构建:
mkdir -p build-simd
cd build-simd
cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
-DNCNN_THREADS=OFF -DNCNN_OPENMP=OFF -DNCNN_SIMPLEOMP=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF -DNCNN_AVX=OFF \
-DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF ..
cmake --build . -j 4
cmake --build . --target install
带 WASM Thread 扩展构建:
mkdir -p build-threads
cd build-threads
cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
-DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=OFF -DNCNN_AVX2=OFF -DNCNN_AVX=OFF \
-DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF ..
cmake --build . -j 4
cmake --build . --target install
带 WASM SIMD 和 Thread 扩展构建:
mkdir -p build-simd-threads
cd build-simd-threads
cmake -DCMAKE_TOOLCHAIN_FILE=../emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake \
-DNCNN_THREADS=ON -DNCNN_OPENMP=ON -DNCNN_SIMPLEOMP=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_SSE2=ON -DNCNN_AVX2=OFF -DNCNN_AVX=OFF \
-DNCNN_BUILD_TOOLS=OFF -DNCNN_BUILD_EXAMPLES=OFF -DNCNN_BUILD_BENCHMARK=OFF ..
cmake --build . -j 4
cmake --build . --target install
选择 build-XYZ/install 文件夹用于进一步使用。
为 AllWinner D1 构建
从 https://occ.t-head.cn/community/download?id=3913221581316624384 下载 c906 工具链包。
tar -xf riscv64-linux-x86_64-20210512.tar.gz
export RISCV_ROOT_PATH=/home/nihui/osd/riscv64-linux-x86_64-20210512
启用 riscv-v 向量和 simpleocv 的 ncnn 构建:
mkdir -p build-c906
cd build-c906
cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/c906.toolchain.cmake \
-DCMAKE_BUILD_TYPE=relwithdebinfo -DNCNN_OPENMP=OFF -DNCNN_THREADS=OFF -DNCNN_RUNTIME_CPU=OFF -DNCNN_RVV=ON \
-DNCNN_SIMPLEOCV=ON -DNCNN_BUILD_EXAMPLES=ON ..
cmake --build . -j 4
cmake --build . --target install
选择 build-c906/install 文件夹用于进一步使用。
你可以将二进制文件上传到 build-c906/examples 文件夹并在 D1 板上运行进行测试。
为 Loongson 2K1000 构建
对于 gcc 版本 <= 8.5,你需要修复 msa.h 头文件以解决 msa fmadd 错误。
打开 /usr/lib/gcc/mips64el-linux-gnuabi64/8/include/msa.h,找到 __msa_fmadd_w 并应用以下更改:
// #define **msa_fmadd_w **builtin_msa_fmadd_w
#define **msa_fmadd_w(a, b, c) **builtin_msa_fmadd_w(c, b, a)
启用 mips msa 和 simpleocv 的 ncnn 构建:
mkdir -p build
cd build
cmake -DNCNN_DISABLE_RTTI=ON -DNCNN_DISABLE_EXCEPTION=ON -DNCNN_RUNTIME_CPU=OFF -DNCNN_MSA=ON -DNCNN_MMI=ON -DNCNN_SIMPLEOCV=ON ..
cmake --build . -j 2
cmake --build . --target install
选择 build/install 文件夹用于进一步使用。
你可以运行 build/examples 文件夹中的二进制文件进行测试。
为 Android 上的 Termux 构建
在手机上安装 Termux 应用,并在 Termux 中安装 Ubuntu。
如果你想使用 ssh,只需在 Termux 中安装 openssh。
pkg install proot-distro
proot-distro install ubuntu
或者你可以使用 proot-distro list 查看可以安装的系统。
在成功安装 Ubuntu 后,使用 proot-distro login ubuntu 登录 Ubuntu。
然后构建 ncnn,无需安装任何其他依赖项。
git clone https://github.com/Tencent/ncnn.git
cd ncnn
git submodule update --init
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DNCNN_BUILD_EXAMPLES=ON -DNCNN_PLATFORM_API=OFF -DNCNN_SIMPLEOCV=ON ..
make -j$(nproc)
然后你可以运行测试:
在我的 Pixel 3 XL 上使用 Qualcomm 845,无法加载
256-ncnn.png
cd ../examples
../build/examples/squeezenet ../images/128-ncnn.png