You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

faq.md 23 kB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. # 如何加入技术交流QQ群?
  2. - 打开QQ→点击群聊搜索→搜索群号637093648→输入问题答案:卷卷卷卷卷→进入群聊→准备接受图灵测试(bushi)
  3. - 前往QQ搜索Pocky群:677104663(超多大佬),问题答案:multi level intermediate representation
  4. # 如何看作者b站直播?
  5. - nihui的bilibili直播间:[水竹院落](https://live.bilibili.com/1264617)
  6. # 编译
  7. - ## 怎样下载完整源码?
  8. git clone --recursive https://github.com/Tencent/ncnn/
  9. 或者
  10. 下载 [ncnn-xxxxx-full-source.zip](https://github.com/Tencent/ncnn/releases)
  11. - ## 怎么交叉编译?cmake 工具链怎么设置啊?
  12. 参见 https://github.com/Tencent/ncnn/wiki/how-to-build
  13. - ## The submodules were not downloaded! Please update submodules with "git submodule update --init" and try again
  14. 如上,下载完整源码。或者按提示执行: git submodule update --init
  15. - ## Could NOT find Protobuf (missing: Protobuf_INCLUDE_DIR)
  16. sudo apt-get install libprotobuf-dev protobuf-compiler
  17. - ## Could NOT find CUDA (missing: CUDA_TOOLKIT_ROOT_DIR CUDA_INCLUDE_DIRS CUDA_CUDART_LIBRARY)
  18. https://github.com/Tencent/ncnn/issues/1873
  19. - ## Could not find a package configuration file provided by "OpenCV" with any of the following names: OpenCVConfig.cmake opencv-config.cmake
  20. sudo apt-get install libopencv-dev
  21. 或者自行编译安装,set(OpenCV_DIR {OpenCVConfig.cmake所在目录})
  22. - ## Could not find a package configuration file provided by "ncnn" with any of the following names: ncnnConfig.cmake ncnn-config.cmake
  23. set(ncnn_DIR {ncnnConfig.cmake所在目录})
  24. - ## 找不到库(需要根据系统/编译器指定)
  25. undefined reference to __kmpc_for_static_init_4 __kmpc_for_static_fini __kmpc_fork_call ...
  26. 需要链接openmp库
  27. undefined reference to glslang::InitializeProcess() glslang::TShader::TShader(EShLanguage) ...
  28. 需要 glslang.lib glslang-default-resource-limits.lib
  29. undefined reference to AAssetManager_fromJava AAssetManager_open AAsset_seek ...
  30. find_library和target_like_libraries中增加 android
  31. find_package(ncnn)
  32. - ## undefined reference to typeinfo for ncnn::Layer
  33. opencv rtti -> opencv-mobile
  34. - ## undefined reference to __cpu_model
  35. 升级编译器 / libgcc_s libgcc
  36. - ## unrecognized command line option "-mavx2"
  37. 升级 gcc
  38. - ## 为啥自己编译的ncnn android库特别大?
  39. https://github.com/Tencent/ncnn/wiki/build-for-android.zh 以及见 如何裁剪更小的 ncnn 库
  40. - ## ncnnoptimize和自定义层
  41. 先ncnnoptimize再增加自定义层,避免ncnnoptimize不能处理自定义层保存。
  42. - ## rtti/exceptions冲突
  43. 产生原因是项目工程中使用的库配置不一样导致冲突,根据自己的实际情况分析是需要开启还是关闭。ncnn默认是ON,在重新编译ncnn时增加以下2个参数即可:
  44. - 开启:-DNCNN_DISABLE_RTTI=OFF -DNCNN_DISABLE_EXCEPTION=OFF
  45. - 关闭:-DNCNN_DISABLE_RTTI=ON -DNCNN_DISABLE_EXCEPTION=ON
  46. - ## error: undefined symbol: ncnn::Extractor::extract(char const*, ncnn::Mat&)
  47. 可能的情况:
  48. - 尝试升级 Android Studio 的 NDK 版本
  49. - ## CMake 3.14.0 or higher is required. You are running version 2.8.12.2
  50. ```shell
  51. wget https://github.com/Kitware/CMake/releases/download/v3.18.2/cmake-3.18.2-Linux-x86_64.tar.gz
  52. tar zxvf cmake-3.18.2-Linux-x86_64.tar.gz
  53. mv cmake-3.18.2-Linux-x86_64 /opt/cmake-3.18.2
  54. ln -sf /opt/cmake-3.18.2/bin/* /usr/bin/
  55. ```
  56. # 怎样添加ncnn库到项目中?cmake方式怎么用?
  57. 编译ncnn,make install。linux/windows set/export ncnn_DIR 指向 install目录下包含ncnnConfig.cmake 的目录
  58. - ## android
  59. - ## ios
  60. - ## linux
  61. - ## windows
  62. - ## macos
  63. - ## arm linux
  64. # 转模型问题
  65. - ## caffe
  66. `./caffe2ncnn caffe.prototxt caffe.caffemodel ncnn.param ncnn.bin`
  67. - ## mxnet
  68. ` ./mxnet2ncnn mxnet-symbol.json mxnet.params ncnn.param ncnn.bin`
  69. - ## darknet
  70. [https://github.com/xiangweizeng/darknet2ncnn](https://github.com/xiangweizeng/darknet2ncnn)
  71. - ## pytorch - onnx
  72. [use ncnn with pytorch or onnx](https://github.com/Tencent/ncnn/wiki/use-ncnn-with-pytorch-or-onnx)
  73. - ## tensorflow 1.x/2.x - keras
  74. [https://github.com/MarsTechHAN/keras2ncnn](https://github.com/MarsTechHAN/keras2ncnn) **[@MarsTechHAN](https://github.com/MarsTechHAN)**
  75. - ## tensorflow 2.x - mlir
  76. [通过MLIR将tensorflow2模型转换到ncnn](https://zhuanlan.zhihu.com/p/152535430) **@[nihui](https://www.zhihu.com/people/nihui-2)**
  77. - ## Shape not supported yet! Gather not supported yet! Cast not supported yet!
  78. onnx-simplifier 静态shape
  79. - ## convertmodel
  80. [https://convertmodel.com/](https://convertmodel.com/) **[@大老师](https://github.com/daquexian)**
  81. - ## netron
  82. [https://github.com/lutzroeder/netron](https://github.com/lutzroeder/netron)
  83. - ## 怎么生成有固定 shape 信息的模型?
  84. Input 0=w 1=h 2=c
  85. - ## why gpu能更快
  86. - ## ncnnoptimize 怎么转成 fp16 模型
  87. `ncnnoptimize model.param model.bin yolov5s-opt.param yolov5s-opt.bin 65536`
  88. - ## ncnnoptimize 怎样查看模型的 FLOPS / 内存占用情况
  89. - ## 怎么修改模型支持动态 shape?
  90. Interp Reshape
  91. - ## 如何将模型转换为代码内嵌到程序里?
  92. ncnn2mem
  93. - ## 如何加密模型?
  94. https://zhuanlan.zhihu.com/p/268327784
  95. - ## Linux下转的ncnn模型,Windows/MacOS/Android/.. 也能直接用吗?
  96. Yes,全平台通用
  97. - ## 如何去掉后处理,再导出 onnx?
  98. 检测:
  99. 参考up的一篇文章<https://zhuanlan.zhihu.com/p/128974102>,步骤三就是去掉后处理,再导出onnx,其中去掉后处理可以是项目内测试时去掉后续步骤的结果。
  100. - ## pytorch 有的层导不出 onnx 怎么办?
  101. 方式一:
  102. ONNX_ATEN_FALLBACK
  103. 完全自定义的op,先改成能导出的(如 concat slice),转到 ncnn 后再修改 param
  104. 方式二:
  105. 可以使用PNNX来试试,参考以下文章大概说明:
  106. 1. [Windows/Linux/macOS 编译 PNNX 步骤](https://zhuanlan.zhihu.com/p/431833958)
  107. 2. [5分钟学会!用 PNNX 转换 TorchScript 模型到 ncnn 模型](https://zhuanlan.zhihu.com/p/427512763)
  108. # 使用
  109. - ## vkEnumeratePhysicalDevices failed -3
  110. - ## vkCreateInstance failed -9
  111. 出现此类问题请先更新GPU驱动。Please upgrade your GPU driver if you encounter this crash or error.
  112. 这里提供了一些品牌的GPU驱动下载网址.We have provided some drivers' download pages here.
  113. [Intel](https://downloadcenter.intel.com/product/80939/Graphics-Drivers),[AMD](https://www.amd.com/en/support),[Nvidia](https://www.nvidia.com/Download/index.aspx)
  114. - ## docker 环境里面 nvidia-smi 能看到显卡也能跑 cuda 却不能跑 vulkan
  115. 因为这个docker环境的nvidia驱动没有安装opengl/vulkan支持
  116. 首先运行 nvidia-smi 查看当前驱动版本
  117. ```
  118. NVIDIA-SMI 535.161.07
  119. Driver Version: 535.161.07
  120. CUDA Version: 12.2
  121. ```
  122. 然后去下载对应版本的NVIDIA驱动,安装用户态驱动文件,跳过内核部分
  123. ```
  124. wget https://us.download.nvidia.com/tesla/535.161.07/NVIDIA-Linux-x86_64-535.161.07.run
  125. chmod +x NVIDIA-Linux-x86_64-535.161.07.run
  126. ./NVIDIA-Linux-x86_64-535.161.07.run --silent --no-kernel-module
  127. ```
  128. 安装时会报一些文件权限错误,不用管,安装完成后 vulkan 支持就可用了。最后安装 vulkaninfo 查看gpu信息
  129. ```
  130. dnf install vulkan-tools
  131. vulkaninfo
  132. ```
  133. - ## ModuleNotFoundError: No module named 'ncnn.ncnn'
  134. python setup.py develop
  135. - ## fopen nanodet-m.param failed
  136. 文件路径 working dir
  137. File not found or not readable. Make sure that XYZ.param/XYZ.bin is accessible.
  138. - ## find_blob_index_by_name data / output / ... failed
  139. layer name vs blob name
  140. param.bin 应该用 xxx.id.h 的枚举
  141. - ## parse magic failed
  142. - ## param is too old, please regenerate
  143. 模型本身有问题
  144. Your model file is being the old format converted by an old caffe2ncnn tool.
  145. Checkout the latest ncnn code, build it and regenerate param and model binary files, and that should work.
  146. Make sure that your param file starts with the magic number 7767517.
  147. you may find more info on use-ncnn-with-alexnet
  148. When adding the softmax layer yourself, you need to add 1=1
  149. - ## set_vulkan_compute failed, network use_vulkan_compute disabled
  150. 你应该在 load_param / load_model 之前设置 net.opt.use_vulkan_compute = true;
  151. - ## 多个blob输入,多个blob输出,怎么做?
  152. 多次执行`ex.input()` 和 `ex.extract()`
  153. ```
  154. ex.input("data1", in_1);
  155. ex.input("data2", in_2);
  156. ex.extract("output1", out_1);
  157. ex.extract("output2", out_2);
  158. ```
  159. - ## Extractor extract 多次会重复计算吗?
  160. 不会
  161. - ## 如何看每一层的耗时?
  162. cmake -DNCNN_BENCHMARK=ON ..
  163. - ## 如何转换 cv::Mat CV_8UC3 BGR 图片
  164. from_pixels to_pixels
  165. - ## 如何转换 float 数据为 ncnn::Mat
  166. 首先,自己申请的内存需要自己管理,此时ncnn::Mat不会自动给你释放你传过来的float数据
  167. ``` c++
  168. std::vector<float> testData(60, 1.0); // 利用std::vector<float>自己管理内存的申请和释放
  169. ncnn::Mat in1 = ncnn::Mat(60, (void*)testData.data()).reshape(4, 5, 3); // 把float数据的指针转成void*传过去即可,甚至还可以指定维度(up说最好使用reshape用来解决channel gap)
  170. float* a = new float[60]; // 自己new一块内存,后续需要自己释放
  171. ncnn::Mat in2 = ncnn::Mat(60, (void*)a).reshape(4, 5, 3).clone(); // 使用方法和上面相同,clone() to transfer data owner
  172. ```
  173. - ## 如何初始化 ncnn::Mat 为全 0
  174. `mat.fill(0.f);`
  175. - ## 如何查看/获取版本号
  176. cmake时会打印
  177. c_api.h ncnn_version()
  178. 自己拼 1.0+yyyymmdd
  179. - ## 如何转换 yuv 数据
  180. yuv420sp2rgb yuv420sp2rgb_nv12
  181. **[@metarutaiga](https://github.com/metarutaiga/xxYUV)**
  182. - ## 如何 resize crop rotate 图片
  183. [efficient roi resize rotate](https://github.com/Tencent/ncnn/wiki/efficient-roi-resize-rotate)
  184. - ## 如何人脸5点对齐
  185. get_affine_transform
  186. warpaffine_bilinear_c3
  187. ```c
  188. // 计算变换矩阵 并且求逆变换
  189. int type = 0; // 0->区域外填充为v[0],v[1],v[2], -233->区域外不处理
  190. unsigned int v = 0;
  191. float tm[6];
  192. float tm_inv[6];
  193. // 人脸区域在原图上的坐标和宽高
  194. float src_x = target->det.rect.x / target->det.w * pIveImageU8C3->u32Width;
  195. float src_y = target->det.rect.y / target->det.h * pIveImageU8C3->u32Height;
  196. float src_w = target->det.rect.w / target->det.w * pIveImageU8C3->u32Width;
  197. float src_h = target->det.rect.h / target->det.h * pIveImageU8C3->u32Height;
  198. float point_src[10] = {
  199. src_x + src_w * target->attr.land[0][0], src_x + src_w * target->attr.land[0][1],
  200. src_x + src_w * target->attr.land[1][0], src_x + src_w * target->attr.land[1][1],
  201. src_x + src_w * target->attr.land[2][0], src_x + src_w * target->attr.land[2][1],
  202. src_x + src_w * target->attr.land[3][0], src_x + src_w * target->attr.land[3][1],
  203. src_x + src_w * target->attr.land[4][0], src_x + src_w * target->attr.land[4][1],
  204. };
  205. float point_dst[10] = { // +8 是因为我们处理112*112的图
  206. 30.2946f + 8.0f, 51.6963f,
  207. 65.5318f + 8.0f, 51.5014f,
  208. 48.0252f + 8.0f, 71.7366f,
  209. 33.5493f + 8.0f, 92.3655f,
  210. 62.7299f + 8.0f, 92.2041f,
  211. };
  212. // 第一种方式:先计算变换在求逆
  213. AffineTrans::get_affine_transform(point_src, point_dst, 5, tm);
  214. AffineTrans::invert_affine_transform(tm, tm_inv);
  215. // 第二种方式:直接拿到求逆的结果
  216. // AffineTrans::get_affine_transform(point_dst, point_src, 5, tm_inv);
  217. // rgb 分离的,所以要单独处理
  218. for(int c = 0; c < 3; c++)
  219. {
  220. unsigned char* pSrc = malloc(xxx);
  221. unsigned char* pDst = malloc(xxx);
  222. ncnn::warpaffine_bilinear_c1(pSrc, SrcWidth, SrcHeight, SrcStride[c], pDst, DstWidth, DstHeight, DstStride[c], tm_inv, type, v);
  223. }
  224. // rgb packed则可以一次处理
  225. ncnn::warpaffine_bilinear_c3(pSrc, SrcWidth, SrcHeight, SrcStride, pDst, DstWidth, DstHeight, DstStride, tm_inv, type, v);
  226. ```
  227. - ## 如何获得中间层的blob输出
  228. ncnn::Mat output;
  229. ex.extract("your_blob_name", output);
  230. - ## 为什么我使用GPU,但是GPU占用为0
  231. windows 10 任务管理器 - 性能选项卡 - GPU - 选择其中一个视图左上角的下拉箭头切换到 Compute_0 / Compute_1 / Cuda
  232. 你还可以安装软件:GPU-Z
  233. - ## layer XYZ not exists or registered
  234. Your network contains some operations that are not implemented in ncnn.
  235. You may implement them as custom layer followed in how-to-implement-custom-layer-step-by-step.
  236. Or you could simply register them as no-op if you are sure those operations make no sense.
  237. ```
  238. class Noop : public ncnn::Layer {};
  239. DEFINE_LAYER_CREATOR(Noop)
  240. net.register_custom_layer("LinearRegressionOutput", Noop_layer_creator);
  241. net.register_custom_layer("MAERegressionOutput", Noop_layer_creator);
  242. ```
  243. - ## network graph not ready
  244. You shall call Net::load_param() first, then Net::load_model().
  245. This error may also happens when Net::load_param() failed, but not properly handled.
  246. For more information about the ncnn model load api, see ncnn-load-model
  247. - ## memory not 32-bit aligned at XYZ
  248. The pointer passed to Net::load_param() or Net::load_model() is not 32bit aligned.
  249. In practice, the head pointer of std::vector is not guaranteed to be 32bit aligned.
  250. you can store your binary buffer in ncnn::Mat structure, its internal memory is aligned.
  251. - ## crash on android with '__kmp_abort_process'
  252. This usually happens if you bundle multiple shared library with openmp linked
  253. It is actually an issue of the android ndk https://github.com/android/ndk/issues/1028
  254. On old android ndk, modify the link flags as
  255. -Wl,-Bstatic -lomp -Wl,-Bdynamic
  256. For recent ndk >= 21
  257. -fstatic-openmp
  258. - ## dlopen failed: library "libomp.so" not found
  259. Newer android ndk defaults to dynamic openmp runtime
  260. modify the link flags as
  261. -fstatic-openmp -fopenmp
  262. - ## crash when freeing a ncnn dynamic library(.dll/.so) built with openMP
  263. for optimal performance, the openmp threadpool spin waits for about a second prior to shutting down in case more work becomes available.
  264. If you unload a dynamic library that's in the process of spin-waiting, it will crash in the manner you see (most of the time).
  265. Just set OMP_WAIT_POLICY=passive in your environment, before calling loadlibrary. or Just wait a few seconds before calling freelibrary.
  266. You can also use the following method to set environment variables in your code:
  267. for msvc++:
  268. SetEnvironmentVariable(_T("OMP_WAIT_POLICY"), _T("passive"));
  269. for g++:
  270. setenv("OMP_WAIT_POLICY", "passive", 1)
  271. reference: https://stackoverflow.com/questions/34439956/vc-crash-when-freeing-a-dll-built-with-openmp
  272. # 跑出来的结果对不上
  273. [ncnn-produce-wrong-result](https://github.com/Tencent/ncnn/wiki/FAQ-ncnn-produce-wrong-result)
  274. - ## 如何打印 ncnn::Mat 的值?
  275. ```C++
  276. void pretty_print(const ncnn::Mat& m)
  277. {
  278. for (int q=0; q<m.c; q++)
  279. {
  280. const float* ptr = m.channel(q);
  281. for (int y=0; y<m.h; y++)
  282. {
  283. for (int x=0; x<m.w; x++)
  284. {
  285. printf("%f ", ptr[x]);
  286. }
  287. ptr += m.w;
  288. printf("\n");
  289. }
  290. printf("------------------------\n");
  291. }
  292. }
  293. ```
  294. In Android Studio, `printf` will not work, you can use `__android_log_print` instead. Example :
  295. ```C++
  296. #include <android/log.h> // Don't forget this
  297. void pretty_print(const ncnn::Mat& m)
  298. {
  299. for (int q=0; q<m.c; q++)
  300. {
  301. for (int y=0; y<m.h; y++)
  302. {
  303. for (int x=0; x<m.w; x++)
  304. {
  305. __android_log_print(ANDROID_LOG_DEBUG,"LOG_TAG","ncnn Mat is : %f", m.channel(q).row(y)[x]);
  306. }
  307. }
  308. }
  309. }
  310. ```
  311. - ## 如何可视化 ncnn::Mat 的值?
  312. ```
  313. void visualize(const char* title, const ncnn::Mat& m)
  314. {
  315. std::vector<cv::Mat> normed_feats(m.c);
  316. for (int i=0; i<m.c; i++)
  317. {
  318. cv::Mat tmp(m.h, m.w, CV_32FC1, (void*)(const float*)m.channel(i));
  319. cv::normalize(tmp, normed_feats[i], 0, 255, cv::NORM_MINMAX, CV_8U);
  320. cv::cvtColor(normed_feats[i], normed_feats[i], cv::COLOR_GRAY2BGR);
  321. // check NaN
  322. for (int y=0; y<m.h; y++)
  323. {
  324. const float* tp = tmp.ptr<float>(y);
  325. uchar* sp = normed_feats[i].ptr<uchar>(y);
  326. for (int x=0; x<m.w; x++)
  327. {
  328. float v = tp[x];
  329. if (v != v)
  330. {
  331. sp[0] = 0;
  332. sp[1] = 0;
  333. sp[2] = 255;
  334. }
  335. sp += 3;
  336. }
  337. }
  338. }
  339. int tw = m.w < 10 ? 32 : m.w < 20 ? 16 : m.w < 40 ? 8 : m.w < 80 ? 4 : m.w < 160 ? 2 : 1;
  340. int th = (m.c - 1) / tw + 1;
  341. cv::Mat show_map(m.h * th, m.w * tw, CV_8UC3);
  342. show_map = cv::Scalar(127);
  343. // tile
  344. for (int i=0; i<m.c; i++)
  345. {
  346. int ty = i / tw;
  347. int tx = i % tw;
  348. normed_feats[i].copyTo(show_map(cv::Rect(tx * m.w, ty * m.h, m.w, m.h)));
  349. }
  350. cv::resize(show_map, show_map, cv::Size(0,0), 2, 2, cv::INTER_NEAREST);
  351. cv::imshow(title, show_map);
  352. }
  353. ```
  354. - ## 总是输出第一张图的结果
  355. 复用 Extractor?!
  356. - ## 启用fp16时的精度有差异
  357. net.opt.use_fp16_packed = false;
  358. net.opt.use_fp16_storage = false;
  359. net.opt.use_fp16_arithmetic = false;
  360. [ncnn-produce-wrong-result](https://github.com/Tencent/ncnn/wiki/FAQ-ncnn-produce-wrong-result)
  361. # 如何跑得更快?内存占用更少?库体积更小?
  362. - ## fp32 fp16
  363. - ## 大小核绑定
  364. ncnn::set_cpu_powersave(int)绑定大核或小核
  365. 注意windows系统不支持绑核。
  366. ncnn支持不同的模型运行在不同的核心。假设硬件平台有2个大核,4个小核,你想把netA运行在大核,netB运行在小核。
  367. 可以通过std::thread or pthread创建两个线程,运行如下代码:
  368. 0:全部
  369. 1:小核
  370. 2:大核
  371. ```
  372. void thread_1()
  373. {
  374. ncnn::set_cpu_powersave(2); // bind to big cores
  375. netA.opt.num_threads = 2;
  376. }
  377. void thread_2()
  378. {
  379. ncnn::set_cpu_powersave(1); // bind to little cores
  380. netB.opt.num_threads = 4;
  381. }
  382. ```
  383. [openmp-best-practice.zh.md](https://github.com/Tencent/ncnn/blob/master/docs/how-to-use-and-FAQ/openmp-best-practice.zh.md)
  384. - ## 查看 CPU 或 GPU 数量
  385. get_cpu_count
  386. get_gpu_count
  387. - ## ncnnoptimize
  388. 使用方式一:
  389. - ./ncnnoptimize ncnn.param ncnn.bin new.param new.bin flag
  390. <br/>注意这里的flag指的是fp32和fp16,其中0指的是fp32,1指的是fp16
  391. 使用方式二:
  392. - ./ncnnoptimize ncnn.param ncnn.bin new.param new.bin flag cutstartname cutendname
  393. <br/>cutstartname:模型截取的起点
  394. <br/>cutendname:模型截取的终点
  395. - ## 如何使用量化工具?
  396. [Post Training Quantization Tools](https://github.com/Tencent/ncnn/tree/master/tools/quantize)
  397. - ## 如何设置线程数?
  398. opt.num_threads
  399. - ## 如何降低CPU占用率?
  400. net.opt.openmp_blocktime = 0;
  401. OMP_WAIT_POLICY=passive
  402. - ## 如何 batch inference?
  403. ```
  404. int max_batch_size = vkdev->info.compute_queue_count;
  405. ncnn::Mat inputs[1000];
  406. ncnn::Mat outputs[1000];
  407. #pragma omp parallel for num_threads(max_batch_size)
  408. for (int i=0; i<1000; i++)
  409. {
  410. ncnn::Extractor ex = net1.create_extractor();
  411. ex.input("data", inputs[i]);
  412. ex.extract("prob", outputs[i]);
  413. }
  414. ```
  415. - ## partial graph inference
  416. 先 extract 分类,判断后,再 extract bbox
  417. - ## 如何启用 bf16s 加速?
  418. ```
  419. net.opt.use_packing_layout = true;
  420. net.opt.use_bf16_storage = true;
  421. ```
  422. [用bf16加速ncnn](https://zhuanlan.zhihu.com/p/112564372) **@[nihui](https://www.zhihu.com/people/nihui-2)**
  423. A53
  424. - ## 如何裁剪更小的 ncnn 库?
  425. [build-minimal-library](https://github.com/Tencent/ncnn/wiki/build-minimal-library)
  426. - ## net.opt sgemm winograd fp16_storage 各是有什么作用?
  427. 对内存消耗的影响
  428. - ## 如何解决显卡进入节能模式造成的一系列问题?
  429. nVidia显卡(Intel和AMD估计也有)会在它认为的所谓空闲模式下,自动进入 `节能模式`,显存和核心频率就都会降低。
  430. 简单来说就是如果你的计算任务是 `非连续的`,那么可能会让耗时看起来非常 `不均匀`,当期间有运算空闲间隔发生,显卡进入节能模式,则会在下一次冷启动时发生计算耗时远超正常耗时几倍的情况,如下日志所示:
  431. ```cpp
  432. //开始播放
  433. Total: 162ms, Diff: 0ms, GLTex2Mat: 7ms, calc: 152ms, Mat2GLTex: 3ms
  434. Total: 43ms, Diff: 0ms, GLTex2Mat: 3ms, calc: 35ms, Mat2GLTex: 2ms
  435. Total: 45ms, Diff: 0ms, GLTex2Mat: 3ms, calc: 37ms, Mat2GLTex: 3ms
  436. Total: 40ms, Diff: 0ms, GLTex2Mat: 3ms, calc: 32ms, Mat2GLTex: 4ms
  437. //暂停3秒
  438. //继续播放
  439. Total: 190ms, Diff: 0ms, GLTex2Mat: 9ms, calc: 177ms, Mat2GLTex: 3ms
  440. Total: 134ms, Diff: 0ms, GLTex2Mat: 5ms, calc: 110ms, Mat2GLTex: 18ms
  441. Total: 40ms, Diff: 0ms, GLTex2Mat: 3ms, calc: 34ms, Mat2GLTex: 2ms
  442. Total: 42ms, Diff: 0ms, GLTex2Mat: 3ms, calc: 36ms, Mat2GLTex: 2ms
  443. Total: 47ms, Diff: 0ms, GLTex2Mat: 5ms, calc: 38ms, Mat2GLTex: 3ms
  444. ...
  445. ```
  446. 在对时间不敏感的项目上,这个问题没什么大不了的,完全可以忽略,但是有些业务场景上必须精准推估下一帧及其未来几帧的从上传、计算到渲染的耗时情况,则这种现象将会给开发者打开些许困扰。
  447. ### 3种解决方法
  448. * 联系显卡厂商,让其更新驱动将你的应用加入到免节能模式的白名单。
  449. * 优点:你什么都不用改。缺点:沟通困难,很可能显卡厂商根本不理你。
  450. * [显卡控制面板] - [管理3D设置] - [电源管理模式],改成:[最高性能优先]。
  451. * 优点:不用改代码。缺点:如果是部署端是小白用户,需要编写手册手把手教他。
  452. * 可以空闲(暂停)时定期灌一些心跳计算包的任务进去(放1x1小图)让GPU维持在高性能状态。
  453. * 优点:需要改代码。缺点:不低碳不环保。
  454. # 白嫖项目
  455. - ## nanodet
  456. # 其他
  457. - ## up主用的什么系统/编辑器/开发环境?
  458. | 软件类型 | 软件名称 |
  459. | ------------| ----------- |
  460. | 系统 | Fedora |
  461. | 桌面环境 | KDE |
  462. | 编辑器 | Kate |
  463. | 画草图 | kolourpaint |
  464. | 画函数图像 | kmplot |
  465. | bilibili直播 | OBS |