【飞桨开发者说】李睿,北京邮电大学学生,人工智能和移动开发爱好者。
随着桌面端Electron技术逐步崛起,基于Electron开发的代码编辑器、聊天软件、游戏等层出不穷。
对于习惯使用Node.js进行后端开发的朋友来说,开发一套漂亮的桌面UI客户端还是有一定难度的;而Electron开发不要太简单,只要会写HTML,就能写客户端,剩下的交给时间慢慢打磨即可。而且,这款开源的技术允许开发者使用JavaScript、HTML 和 CSS 构建跨平台的桌面应用程序。不同平台UI效果和网页显示效果一致,非常易用。
那么在桌面客户端上面,我们能否帮开发者实现本地部署Paddle Lite进行推理呢?答案是肯定的。Paddle Lite提供C++接口,并且在2.6.0版本中支持了Windows开发环境。这为我们将Paddle Lite封装成Node.js的C++插件提供了可能。如果能够成功移植,开发桌面应用的时候就可以实现在客户端上完成图片分类等任务。同时Paddle Lite提供的模型非常轻量化,常规PC机足以跑出不错的性能。
而且,对于其他Node.js场景来说,比如网站后端,也可以直接使用Paddle Lite进行推理。
于是我做了一个Demo,其本质上是将Paddle Lite的C++ API封装为Paddle Lite类,这个类目前提供了两个方法,分别是set_model_file和infer_float。在此之上,我使用N-API来编写Node.js插件,将其组合起来,允许Node.js调用Paddle Lite的C++ API。
项目效果
paddlenode.node :编译后的Node.js模块 libiomp5md.dll :OpenMP DLL mklml.dll :MKL数学核心库
pip install paddlelite
paddle_lite_opt –model_dir=./mobilenet_v1 –valid_targets=x86 –optimize_out=mobilenetv1_opt
var addon = require('./paddlenode') var arr = new Array(150528) for(var i=0; i<arr.length; i++) arr[i]=1; addon.set_model_file("./mobilenetv1_opt.nb") addon.infer_float(arr,[1, 3, 224, 224])

手动编译
{ 'variables': { 'lite_dir%': 'C:/Users/Li/Desktop/Exp/inference_lite_lib.win.x86.MSVC.C++_static.py37.full_publish', }, "targets": [ { 'target_name': "paddlenode", 'sources': ["paddlelib.h","paddlelib.cc","paddlenode.cc"], 'defines': [ ], 'include_dirs': [ "<(lite_dir)/cxx/include", "<(lite_dir)/third_party/mklml/include" ], 'libraries': [ "-l<(lite_dir)/cxx/lib/libpaddle_api_light_bundled.lib", "-l<(lite_dir)/third_party/mklml/lib/libiomp5md.lib", "-l<(lite_dir)/third_party/mklml/lib/mklml.lib", "-lshlwapi.lib" ] } ] }
node-gyp configure build
原理介绍
napidefineproperties - 定义资源 napigetcb_info - 获取调用的信息 napithrowerror - 抛出错误 napitypeo - 获取napivalue的类型 napigetvaluestringutf8 - 将napi_value转换为utf8字符串 napigetarraylength - 获取napivalue对应的数组长度 napigetvaluedouble - 获取napivalue对应的双精度数组元素 napigetvalueint32 - 将napivalue转换为32位整型 napigetvaluedouble - 将napivalue转换为双精度浮点数 napicreatedouble - 将双精度浮点数转换为napi_value
写在最后
参考链接