本文内容来自ling9601在MNN GitHub中issues_1051的回答,加上笔者实测过程中的一些注释。
由于MNN没有用于树莓派4B的pip安装包,所以需要在树莓派上使用python版的MNN的话可以自己编译whl文件,然后安装。
或者直接尝试安装笔者编译的whl包:点这里,安装失败再自行编译。
笔者使用的树莓派4B系统为2021-05-07-raspios-buster-armhf
,内存4GB。
-
安装编译依赖
sudo apt-get install cmake libprotobuf-dev protobuf-compiler
-
克隆MNN源代码
git clone https://github.com/alibaba/MNN
原文说RangiLyu/nanodet#92用了1.0.0的版本,但是ling9601发现当时的最新版本1.1.3更快并且支持多线程,所以他用了当时最新版本1.1.3。笔者实测现在最新版本1.2.7编译会报错(可能因为后边python版本的原因没有编译成功,但是1.1.3编译出来的whl已经能够正常使用,有余力的朋友可以试着编译一下最新版本)。
所以切换到1.1.3版本:
git checkout 1.1.3
-
编译准备:
cd /path/to/MNN # 切换到MNN根目录即可 ./schema/generate.sh mkdir pymnn_build
-
为python wheel的搭建搭建依赖:
如果同时编译
MNNConvert
,会报下边的错误,并且没有解决方案。[100%] Linking CXX executable ../../MNNConvert /usr/bin/ld: /usr/local/lib/libprotobuf.a(arena.o): in function google::protobuf::internal::ArenaImpl::Init(bool)': arena.cc:(.text+0x3ac): undefined reference to __atomic_fetch_add_8' collect2: error: ld returned 1 exit status
所以不编译
MNNConvert
。修改下边的代码MNN/pymnn/pip_package/build_deps.py ... elif IS_LINUX: os.system('cmake -DMNN_BUILD_CONVERTER=on -DMNN_BUILD_TRAIN=ON -DCMAKE_BUILD_TYPE=Release\ -DMNN_BUILD_SHARED_LIBS=OFF -DMNN_AAPL_FMWK=OFF -DMNN_SEP_BUILD=OFF\ -DMNN_USE_THREAD_POOL=OFF .. && make MNN MNNTrain MNNConvert -j4') ...
改为:
MNN/pymnn/pip_package/build_deps.py ... elif IS_LINUX: os.system('cmake -DMNN_BUILD_CONVERTER=on -DMNN_BUILD_TRAIN=ON -DCMAKE_BUILD_TYPE=Release\ -DMNN_BUILD_SHARED_LIBS=OFF -DMNN_AAPL_FMWK=OFF -DMNN_SEP_BUILD=OFF\ -DMNN_USE_THREAD_POOL=OFF .. && make MNN MNNTrain -j4') ...
就是把最后的
MNNConvert
删去。使用
build_deps.py
编译依赖:cd pymnn/pip_package python build_deps.py #这一步建议在虚拟环境下运行,确保python指的是python3而不是2.7,我发现即便把该命令中的python改为python3,运行的时候,代码会自己找到2.7版本的python去编译,显示Found PythonInterp: /usr/bin/python (found version "2.7.16"),最后得到的whl文件是MNN-1.1.3-cp27-cp27m-manylinux2014_armv7l.whl而不是MNN-1.1.3-cp37-cp37m-manylinux2014_armv7l.whl,pip install直接显示不支持。
-
编译 wheel
修改代码中的平台:
MNN/pymnn/pip_package/build_wheel.py ... if IS_LINUX: os.system('python setup.py bdist_wheel --plat-name=manylinux1_x86_64') ...
改为:
pymnn/pip_package/build_wheel.py ... if IS_LINUX: os.system('python setup.py bdist_wheel --plat-name=manylinux2014_armv7l') ... # 这一步和我改的时候的代码不太一样,目前看直接改成这个plat-name就可以
不能编译
_tools
,要把下列代码注释掉:pymnn/pip_package/setup.py ... tools = Extension("_tools",\ libraries=tools_libraries,\ sources=tools_sources,\ language='c++',\ extra_compile_args=tools_compile_args + extra_compile_args,\ include_dirs=tools_include_dirs,\ library_dirs=tools_library_dirs,\ extra_link_args=tools_extra_link_args +tools_link_args\ + [make_relative_rpath('lib')]) extensions.append(tools) ...
运行编译:
python build_wheel.py --version 1.1.3 # 原文没有version参数,报错了,可能是代码发生变化了吧 # 这一步同样虚拟环境,确保python代表python3 # 运行的时候numpy报错了。。奇怪,但是wheel包还是生成了
-
安装wheel文件
pip install pymnn/pip_package/dist/MNN-1.1.3-cp37-cp37m-manylinux2014_armv7l.whl
-
测试MNN包的安装
import MNN
因为没有编译
_tools
,所以会出现以下报错:>>> import MNN Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/pi/.virtualenvs/mnn/lib/python3.7/site-packages/MNN/__init__.py", line 9, in <module> from . import tools File "/home/pi/.virtualenvs/mnn/lib/python3.7/site-packages/MNN/tools/__init__.py", line 1, in <module> from . import mnn, mnnops, mnnquant, mnnconvert File "/home/pi/.virtualenvs/mnn/lib/python3.7/site-packages/MNN/tools/mnnquant.py", line 8, in <module> import _tools as Tools ModuleNotFoundError: No module named '_tools'
修改python程序中的以下文件:
/lib/python3.7/site-packages/MNN/__init__.py ... from . import tools ...
重新测试
import MNN
,没问题了啊啊啊啊啊啊啊啊啊啊啊啊啊成功了!!!!!!!!!啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
推理是没有问题的,使用1920*1080的视频帧率为2 FPS,网络摄像头640*480的视频帧率为8.4 FPS,比使用yolov5n模型识别好了数十倍,yolov5n模型不管什么视频帧率都约为0.2 FPS,比ppt还卡。
数据比较主观,可以自行实验。