スマートフォン上でAI推論を完結させる「オンデバイス推論」アプリが増えています。
野鳥の鳴き声を圏外でも識別するTrailWhistleはその典型例です。
本記事は、こうしたアプリをクラウド運用の感覚で監視設計すると何が起きるかを整理します。
オンプレ・クラウド移行を担当してきたエンジニアほど、監視設計は「サーバー側に全部ログが集まる」前提で考えがちです。
ところがTrailWhistleのような構成では、推論処理そのものがユーザーの手元で完結し、サーバーには何も飛んできません。
この前提のズレが、障害対応を迷子にする落とし穴になります。
何が起きるか:サーバーは健康なのにユーザーは困っている
TrailWhistleはReact製のPWA(Progressive Web App、ブラウザで動くがアプリのように振る舞うWeb技術)として実装されています。
中核はBirdNET v2.4という、コーネル大学鳥類学研究所とケムニッツ工科大学が開発した音響識別モデルです。
このモデルがONNX(Open Neural Network Exchange、機械学習モデルを異なる実行環境間で共有するための標準フォーマット)形式に変換され、WebAssembly(ブラウザ上でネイティブに近い速度でコードを実行する技術)としてブラウザ内で動きます。
つまり推論はユーザーの端末内のWeb Worker(UIをブロックせずバックグラウンド処理を行う仕組み)で完結し、サーバーには一切のリクエストが飛びません。
配信元のサーバーが担うのは、最初にアプリ本体とモデルファイル(約47MB)を配るところまでです。
ここで典型的に起きるのが「サーバー監視は全部グリーンなのに、ユーザーからは不具合報告が来る」という状況です。
APIのレスポンスタイムもエラー率も正常、しかし実際には端末側でモデルのロードに失敗していたり、推論結果が常に「Unknown」になっていたりします。
サーバー中心の監視ダッシュボードには、この種の障害がそもそも映りません。
なぜ起きるか:監視の前提がサーバー中心のまま変わっていない
原因を分解すると、いくつかの段階に分かれます。
1段階目は、従来型のAPM(Application Performance Monitoring、アプリケーションの性能を監視する仕組み)がリクエスト・レスポンスのペアを前提に設計されている点です。
オンデバイス推論では「リクエスト」に相当する処理がユーザーの端末内で閉じてしまうため、APMの観測範囲の外側で障害が発生します。
2段階目は、Service Worker(ブラウザがバックグラウンドで通信を仲介・キャッシュする仕組み)によるオフラインファースト設計そのものが、可観測性を犠牲にしている点です。
TrailWhistleはアプリ本体・モデル重み・分類に必要な種のリストをService Workerでキャッシュし、2回目以降はネットワークなしで動作します。
これは機能としては優秀ですが、キャッシュが壊れた・古いモデルが残り続けている、といった状態はサーバーログには一切残りません。
3段階目は、信頼度のしきい値のような「アプリ内部のロジックの劣化」が外部から見えないことです。
TrailWhistleは信頼度が25%を下回ると誤判定を避けるため「Unknown」と返す設計になっています。
開発段階では低確信度でも種名を出力していたものの、現場ツールとして誤答の害が大きいと判断し、その挙動を取り除いたという経緯があります。
この種のしきい値調整はアプリ内のロジックであり、サーバー側の監視からは完全に不可視です。
自分のプロジェクトが該当するか確認する方法
まず、担当しているアプリやサービスがオンデバイス推論・PWA・オフラインファーストのいずれかに該当するか確認します。
manifest.jsonやservice-worker.js(sw.js)がリポジトリに存在するか確認する(PWAである可能性)- 推論処理のコード内に
onnxruntime-web、tensorflow.js、WebAssemblyといった文言があるかgrepする - ネットワークタブ(ブラウザ開発者ツール)で推論実行時にAPIコールが発生しているかを目視確認する
Cache Storage(ブラウザのキャッシュAPI)にモデルファイルや大きなバイナリが保存されていないか確認する
# リポジトリ内でオンデバイス推論の痕跡を探す
grep -rliE "onnxruntime|tensorflow.js|webassembly|service-worker" ./src ./publicこのコマンドでヒットがあれば、サーバーサイドのAPM・ログ監視だけでは障害の全体像を捉えきれない可能性があります。
逆に何もヒットしない従来型のサーバーサイドAPIであれば、本記事で扱う落とし穴は該当しません。
対策の手順
該当する場合、以下の手順でクライアントサイドの可観測性を補強します。
1. クライアントエラーレポーティングを導入する
SentryやDatadog RUM(Real User Monitoring、実際のユーザー端末での挙動を計測する仕組み)など、ブラウザ側の例外を収集できるツールを導入します。
モデルのロード失敗、WebAssemblyの初期化エラー、Service Workerの登録失敗を個別にキャッチし、タグ付けして送信する設計にします。
2. 推論結果の分布を匿名集計で送る
TrailWhistleの「Unknown」判定率のような、推論結果の分布そのものが品質指標になります。
個人を特定しない形で、信頼度の分布やUnknown率を定期的にサーバーに送信するバッチ処理を仕込むと、モデル劣化やキャッシュ破損の兆候を早期に拾えます。
3. Service Workerのバージョニングを監視する
キャッシュされているモデルファイルやアプリシェルのバージョンを、起動時にサーバー側の最新バージョンと突き合わせる仕組みを入れます。
古いキャッシュが残り続けているユーザー比率が可視化できれば、障害対応の初動が「サーバーを疑う」から「クライアントのキャッシュを疑う」に切り替わります。
4. オフライン時の挙動をSLO(Service Level Objective、サービス品質の目標値)に含める
従来の可用性SLOは「サーバーが正常に応答した割合」で測りがちです。
オンデバイス推論アプリでは「端末内で推論が正常に完了した割合」を別のSLOとして定義し、クライアントから送られる成功・失敗イベントで計測します。
5. 運用コストの見直し
オンデバイス推論はサーバー側の推論コスト(GPUインスタンス代やAPI呼び出し課金)を削減できる一方、クライアント監視ツールの導入・運用コストが新たに発生します。
SentryやDatadog RUMの課金はイベント数やセッション数に応じるため、PWAのようにユーザー数が増えるほど監視コストも比例して増える点は予算計画に織り込んでおく必要があります。
確認しておきたいこと
オンデバイス推論を含むアプリの監視では、次の3点を起点に見直すと整理しやすくなります。
manifest.jsonやService Workerの有無をgrepで確認し、該当するか判断する- サーバーAPMだけでなくクライアントエラーレポーティング(Sentry等)を導入し、端末側の失敗を可視化する
- 「サーバーの可用性」と「端末内推論の成功率」を別々のSLOとして定義する
クラウド移行の経験が長いほど、サーバー中心の監視設計が染みついています。
オンデバイス推論のような構成に出会ったときは、一度「障害はどこで起きうるか」を端末側まで含めて洗い出し直すところから始めてみてください。