Posenet を WebWorker で動かしてみた
デモはここで試せる https://posenet-worker.netlify.com/
コードはここ github.com
構成
- getUserMedia でカメラ取得
- OffscreenCanvas でバックグラウンドの書き込み
- Tensorflow.js + Posenet
Tensorflow.js が Chrome では webgl バックエンドになったとの目撃談があったので、試してみた。
[https://twitter.com/sugyan/status/1156616432248971264:embed#動作を試せるやつ上げた。Chromeだと WebWorkerでMainThreadの動き止めずにwebglで高速に処理してくれてそう https://t.co/GsepIMRSqG https://t.co/je8ceda47L]
今の所、Chrome 以外では tensorflow.js が cpu_backend にフォールバックしてしまう。webgl_backend で動けば速い。
Can I use... Support tables for HTML5, CSS3, etc
Firefox は Experimental
感想
ほぼ全ての処理を Worker に逃したので、 メインスレッドの負荷は極小だが、モデルが温まる?までが遅い。10秒ぐらい待つ必要がある。このスロースタート感は JIT が効くのを待っているような気がするが、そこのコードまでちゃんと読んでないので確証はない。
ただし、GPUがカツカツ
video を worker に送るために Transferrable な ImageBitmap を送れればいいと思ったのだが、 video が transferrable 要素ではないので、一旦 OffscreenCanvas を作って video 要素を drawImage して transfer している。
https://github.com/mizchi/posenet-worker/blob/master/src/index.ts#L34-L39
一旦 video => canvas の転写が走るので worker に逃がす旨味が少し減った。とはいえメインスレッド専有は 0.5ms ぐらいで済んでて、これなら何かに使えそうな気がする。
あとこれは開発者特有の問題だと思うが、このコードを書きながらDiscordで通話していると、書いてる2時間の間にOSが4回クラッシュした。