スマホで、画像認識AIを動かしたい!
スマホのカメラで、リアルタイムで物を認識したい。
しかも、アプリじゃなくて、ブラウザで動かしたい。
というわけで、実際に作ってみた。
公開もしているから、実際に試せる。
スマホでアクセスするだけでOK。
物体検出とは?
今回やっているのは、リアルタイム物体検出だ。
物体検出というのは、AIが「何が写っているか」と「どこにあるか」を認識する技術。
例えばカメラを向けると、
「これは本」
「これはノートPC」
という感じで、何が写っているのかを認識してくれる。
しかも、画面のどこにあるのかまで教えてくれる。
工場の製品仕分けや自動運転、防犯カメラなど、いろんなところで使われている技術だ。
今回のポイントは、これをスマホで動かしていること。
普通、AIモデルはスマホでは動かさない。
性能が足りないから。
だから普通は、サーバーで動かす。
要するに、パワフルなPCに処理を任せるわけだ。
でも、それには問題が3点ある。
サーバーで動かしたくない理由
遅延
リアルタイム物体検出では、速度が重要だ。
サーバーで処理する場合は、カメラ画像をサーバーへ送ることになる。そして、処理をして、結果を返してもらう。
つまり、通信の往復が必要。
当然、そのぶん時間がかかる。
リアルタイム性を求めるなら、これは痛い。
例えば自動運転。
ブレーキが0.5秒遅れたら困る。
リアルタイム処理では、少しの遅延でも無視できない。
お金
サーバーはタダじゃない。
AIを動かせるサーバーを借りるなら、お金がかかる。
でも、スマホでAIを動かせるなら?
サーバーがいらない。
だから無料!
個人開発にも嬉しい。
個人開発はできるだけ金をかけたくない。
このメリットはかなり大きい。
プライバシー
シンプルに、スマホの映像を外部へ送りたくない。
「ちゃんとプライバシーを守ってくれるよね?」と開発者を信用しないといけない。
その点、スマホで動かせば、映像を外部に送らなくて済む。
プライバシーの面でも安心だ。
個人的には、一番大きいのはお金。
サーバーでAIモデルを動かさなければ、完全無料でサービスを公開することだってできる。
最初のデモページも無料だ。
どれだけアクセスされようが、私の懐は一切痛まない。
これで、サーバーで動かしたくない理由は分かった。
では、本題。
どうやってスマホでAIモデルを動かすのか?
スマホでAIモデルを動かす
答えは意外にもシンプル。
軽いモデルを使えばいい。
普通、AIモデルをサーバーで動かすのは、処理が重いからだ。
だったら、軽いモデルを使えばいい。
今回使ったのは、NanoDet-Plusという物体検出モデル。
正確には、NanoDet-Plus-m-320をONNX形式に変換したものだ。
ONNXについては後で説明する。
NanoDet-Plusの特徴は、とにかく軽いこと。
モデルサイズは、たったの6MB1。
大きめの画像数枚分ぐらいしかない。
しかも速い。
リアルタイム物体検出向けに作られたモデルなので、今回の用途にはぴったりだ。
特に嬉しいのが、ライセンスの緩さ。
物体検出といえばYOLOが有名。特にUltralyticsのYOLO。
ただ、ライセンスがちょっと面倒。
どうやら、Ultralytics YOLOを使ったアプリを公開する場合は、ソースコードの公開が必要らしい。
参考:
例えば、企業にとって、これは厳しいだろう。
一方、NanoDet-Plusはそういう心配がない。商用利用もOK。
個人開発でも、企業でも安心して使える。
さらに言うと、ブラウザで動かしたい。
ブラウザなら、iPhoneでもAndroidでも動く。
使う側も楽。
アプリをダウンロードしなくていい。
サイトにアクセスするだけ。
でも、本当にブラウザでAIモデルなんて動かせるのか?
答えは、ONNXならいける。
ONNXは、AIモデルの形式だ。
この形式にしておくと、いろんな環境で動かせるようになる。
Pythonでも動くし、C++でも動く。
そして何より、ブラウザでも動く。
だから今回も、ブラウザ上でAIモデルを動かせた。
より正確に言うと、ONNXファイルだけでは動かない。
実行環境が必要だ。その実行環境がONNX Runtime。
ゲームで例えよう。
ゲームソフトだけ買っても遊べない。
ゲーム機が必要だ。SwitchやPS5とかね。
ONNXも同じ。
ONNXファイルだけでは動かせない。
ONNX Runtimeという「ゲーム機」があって、初めて動く。
そして、Web向けのONNX RuntimeがONNX Runtime Web。
つまり、ブラウザでAIモデルを動かしたいなら、
- AIモデルをONNX形式に変換
- ONNX Runtime Webで実行
すればいい。
でも、遅いんじゃないの?
リアルタイム物体検出なので、一番気になるのは速度。
例えば1FPSしか出なかったら、リアルタイムとは言えない。
ブラウザ×スマホなので、かなり遅くなると思っていた。
でも、実際に動かしてみると、意外と速い。
今回使ったスマホは、Google Pixel 9a。
この環境で測ったところ、10FPSほど出た。
モデルの推論時間は100msほど。
「めちゃくちゃ速い!」というほどではない。
でも、普通にリアルタイムで使えるレベル。
昔、低スペックPCでゲームを10FPSぐらいで遊んでいた記憶がある。
それを思えば、十分実用的だ。
ただし、速度のブレが激しい。
調子がいいと16FPSぐらい出る。
逆に、悪いと8FPSぐらいまで落ちる。
なんでこんなにブレるのかは分からない。
いずれにしても「使い物にならない」という感じではない。
用途しだいでは、十分実用的だと思う。
まとめ
今回のポイントは、「スマホでAIを動かした」ことだけじゃない。
本質は、エッジデバイスでもAIが動くことを確認したことだ。
エッジデバイスというのは、ざっくり言えば性能の低いコンピュータのこと。
スマホも、その一つだ。
だから今回の話は、スマホだけに限らない。
Webである必要もない。
ONNXは、PythonでもC++でも動く。
つまり、ラズパイみたいなエッジデバイスでも同じことができる。
「AIはサーバーで動かすもの。」
前まではそう思っていた。
実際にやってみると、スマホでも普通に動く。
やっぱり、試してみるものだ。
コード
-
今回使用したNanoDet-Plus-m-320のONNXモデル(量子化なし)のサイズ。モデル形式や量子化の有無によってサイズが変わる。公式githubによると、int8なら1MBまで減らせるらしい。 ↩