ONNX.jsで実現するクロスプラットフォームAI推論:ブラウザでモデルを動かす実践ガイド

2025年12年03日カテゴリー: 技術記事
タグ:ONNX.jsJavaScript機械学習AIクロスプラットフォーム

ONNX.jsを使えば、学習済みのAIモデルをWebブラウザやNode.js上で直接実行できます。この記事では、ONNX.jsの基本から、クロスプラットフォーム推論を実現するための具体的な手法、そして実践的なベストプラクティスまでをコード例と共に徹底解説します。

ONNX.jsとは? なぜ今注目されるのか

ONNX (Open Neural Network Exchange) は、AIモデルをフレームワーク間で共有するためのオープンなフォーマットです。そして、ONNX.jsは、このONNX形式のモデルをJavaScript環境、つまりWebブラウザやNode.js上で直接実行するためのライブラリです。これにより、これまでサーバーサイドで行うのが常識だったAIの推論処理を、クライアントサイドで完結させることが可能になります。 クライアントサイドでAIを動かすメリットは計り知れません。

  • 低遅延: サーバーとの通信が不要なため、リアルタイム性が求められるアプリケーション(例: カメラエフェクト)で高速な応答が可能です。 プライバシー保護: ユーザーのデータをサーバーに送信する必要がなく、手元のデバイス内で処理が完結するため、プライバシーが向上します。 サーバーコスト削減: GPUサーバーなどの高価なインフラを維持する必要がなくなり、スケーラビリティの問題からも解放されます。

ONNX.jsが解決する「クロスプラットフォームの壁」

従来のAI開発では、Python(PyTorchやTensorFlow)で学習したモデルを、Web、iOS、Androidなど各プラットフォーム向けに変換・再実装する必要があり、膨大なコストと時間がかかっていました。ONNXとONNX.jsは、この開発フローを劇的に簡素化します。 以下の図は、従来の手法とONNX.jsを利用した開発フローの違いを示しています。

「一度学習すれば、どこでも動く(Train once, run anywhere)」が実現し、開発者はモデルの本質的な改善に集中できるようになります。

ONNX.jsの実行バックエンドを選択する

ONNX.jsは、内部で処理を実行するための「バックエンド」を切り替えることができます。環境やモデルの特性に応じて最適なバックエンドを選択することが、パフォーマンス向上の鍵となります。

バックエンド パフォーマンス 互換性 主なユースケース
cpu 低 非常に高い 小規模モデル、デバッグ、フォールバック用 wasm 中 高い (モダンブラウザ) CPU負荷の高い処理、汎用的なモデルに最適 webgl 中〜高 高い (GPU搭載デバイス) 画像処理、CNN(畳み込みニューラルネットワーク)モデル webgpu 非常に高い 限定的 (最新ブラウザのみ) 次世代API。大規模モデル、最高のパフォーマンスを追求する場合

基本的には、汎用性の高いwasmを第一候補とし、画像処理などGPUの並列計算が活きる場面ではwebglを検討するのが良いでしょう。

実践!ONNX.jsで画像分類モデルを動かしてみよう

それでは、実際に事前学習済みの画像分類モデル(MobileNetV2)をブラウザで動かしてみましょう。

ステップ1: 準備

まず、ONNX.jsライブラリをプロジェクトに追加します。npmやyarnを使うか、CDNから直接読み込みます。 npm install onnxjs

次に、推論に使用するONNXモデルファイル(例: mobilenetv2.onnx)を用意し、Webサーバーからアクセスできる場所に配置します。

ステップ2: モデルの読み込みとセッションの作成

JavaScriptコードで、モデルを非同期に読み込み、推論セッションを作成します。ここで実行バックエンドを指定します。 import * as ort from 'onnxjs'; async function createSession() { try { // バックエンドとしてWASMを指定してセッションを作成 const session = await ort.InferenceSession.create('./mobilenetv2.onnx', { executionProviders: ['wasm'], graphOptimizationLevel: 'all' }); console.log('ONNXモデルのセッション作成に成功しました。'); return session; } catch (e) { console.error(`モデルの読み込みに失敗しました: ${e}`); return null; } } const mySession = await createSession();

ステップ3: 入力データの準備

AIモデルは特定の形状とデータ型を持つ多次元配列、すなわち「テンソル」を入力として受け取ります。画像データを読み込み、モデルが要求する形式(例: 1x3x224x224 の浮動小数点数テンソル)に前処理する必要があります。 // この関数は、画像要素をモデル入力用テンソルに変換する例です // 実際にはライブラリを使うか、Canvas APIでピクセル操作を行います function preprocessImage(imageElement) { // ここでリサイズ、正規化、次元の並べ替えなどを行う const dims = [1, 3, 224, 224]; const size = dims.reduce((a, b) => a * b); // ダミーデータを作成 const inputData = new Float32Array(size); for (let i = 0; i < size; i++) { inputData[i] = Math.random() * 2.0 - 1.0; // -1.0から1.0の範囲に正規化 } const inputTensor = new ort.Tensor('float32', inputData, dims); return inputTensor; } const image = document.getElementById('my-image'); const inputTensor = preprocessImage(image);

ステップ4: 推論の実行と結果の解釈

準備した入力テンソルをセッションに渡し、runメソッドで推論を実行します。結果もまたテンソルとして返ってくるので、後処理を行って人間が理解できる形式に変換します。 async function runInference(session, tensor) { // モデルの入力名('input'など)に合わせてフィードを作成 const feeds = { 'input': tensor }; // 推論を実行 const results = await session.run(feeds); // モデルの出力名('output'など)で結果を取得 const outputTensor = results.output; console.log('出力データ:', outputTensor.data); // ここで後処理(例: argmaxで最も確率の高いクラスを見つける)を行う // ... } if (mySession) { await runInference(mySession, inputTensor); }

ONNX.js利用時のベストプラクティス

  • モデルの最適化: モデルをWebで利用する前に、量子化や枝刈りを行い、ファイルサイズを削減しましょう。読み込み時間が短縮され、ユーザー体験が向上します。 非同期処理とUI: モデルの読み込みや推論は重い処理です。Web Workerを使ってメインスレッドをブロックしないようにし、処理中はローディングインジケーターを表示しましょう。 バックエンドのフォールバック: try...catch構文を使い、webglが失敗したらwasmに、wasmが失敗したらcpuに切り替える、といったフォールバック機構を実装すると、より多くの環境でアプリケーションが動作するようになります。

まとめ

ONNX.jsは、ONNXモデルをJavaScript環境で実行するための強力なライブラリです。プラットフォームごとにAIモデルを再実装する手間を省き、Webブラウザ上で直接、高速かつプライベートな推論を実現します。この記事で紹介した基本とベストプラクティスを活用し、あなたのWebアプリケーションにAIの力を組み込んでみましょう。