Posenet を WebWorker で動かしてみた

https://i.gyazo.com/0c983c60a17e705fae88ae58ca75f432.gif

デモはここで試せる 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 が効くのを待っているような気がするが、そこのコードまでちゃんと読んでないので確証はない。

https://i.gyazo.com/802cc5893cb97f49d52b81bda66c6d0a.png

ただし、GPUがカツカツ

https://i.gyazo.com/785b79afdf56121c10f1b927e028e2ef.png

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回クラッシュした。