微信小程序下运行最新TensorFlowJS
(3.6)的工程解决方案,有以下特点
- 运行 balzeface 安卓 √,IOS √
- 运行 face-landmarks 安卓 √,IOS √
- 集成 tfjsPlugin,方便使用,无需二次引用 √
- 支持 wasm backend √ 给 tfjs 提的PR已合并
- 运行 posenet (例子是 mobilenet 0.50 stride16) √
- custom tfjs 减少包体积 blazeface 例子 √
- 运行 handpose √
性能数据
机器 |
模型 |
FPS |
Backend |
MI 8 |
BlazeFace |
20 |
WebGL |
MI 8 |
BlazeFace |
17 |
WASM |
IPhone 7 |
BlazeFace |
12 |
WebGL |
IPhone 7 |
BlazeFace |
1 |
WASM |
注:WASM 为非 SIMD 版,安卓微信小程序运行 SIMD WASM 报错
虽说能跑,但是微信 IOS 上面问题多多,建议能 webview 还是 webview,性能好,gl 起码符合标准也无内存问题
问题
- ios async 版本会卡 async await,所以改为 sync 版本,并且其他用到 async await 也可能出现( IOS 下 Promise 是 setTimeout 模拟的,见小程序 JavaScript 支持情况)目前 ios 下比较容易卡初始化
- wasm 只有在华为手机上比 webgl 好 (2.7 测试的结果)
优化经验
- 使用 FrameAdapter 动态跳帧处理
- 正式处理数据前,预热处理一个空白帧,把所用到的 shader 编译
- 利用 profile 生成 custom tfjs 优化包大小
- 微信小程序 cameraFrame 的 ArrayBuffer 是复用的,可能推理完成后,内容就被更新了,所以先绘制背景,再绘制推理结果,另种解法是拿到相机帧时候复制一份(iPhone7 大概 0~5ms, 大部分是 1ms)
运行
> pnpm i / npm i / yarn
> npm run dev
# 使用小程序开发工具打开,替换 appid 为测试 appid,不校验域名
# 使用 custom tfjs 编译,例子是仅仅 blazeface 可用 tf + webgl backend 小程序包从 985KB 下降到 534KB (js 大概下降 234KB)
> npm run make-custom
> npm run build-custom
TODO
- 结果 UI 美化
- face-api.js
- warm up 通用化,根据已注册的 registerKernel 做 warm up
使用 custom_tfjs 进一步优化包大小
请参考
- [962K -> 347K] TensorflowJS 基于 Runtime 结果的 TreeShaking
- https://github.com/mattsoulanille/tfjs_custom_module_demo
- https://github.com/deepkolos/tfjs-treeshaking-test
tfjs-models async 转 sync 方法
只需要把读取数据部分的 async 方法比如Tensor.array()
改为Tensor.arraySync()
,或者Tensor.buffer()
改为Tensor.bufferSync()
,然后把async
和await
,Promise.all
等关键字去除,即可